Associating Access Control Lists (ACLs) with files is the fundamental mechanism for securing file system data. Consequently, the #1 rule for securely storing data in files is to ensure the proper ACLs are on your files.
Using NTFS so you can have ACLs is not enough. You need to know what ACLs you want to put on your files, and you need to know how to go about putting ACLs on your files so you can avoid common mistakes. For determining what ACLs to put on files, refer to Writing Secure Code, pages 95 – 98. This post will deal with how you go about ensuring the ACLs you want are actually on the files you want. There are several common misconceptions about ACLs in the file system that can lead to security holes. However, if you obey the following rules, you should be able to properly ACL your data.
1. Rely only on the ACL on the file to provide security
This rule seems so obvious that nobody could get it wrong: if you want to secure access to a file, you put an ACL on that file. However, there are several well-intentioned ways to violate this rule. Consider the following:
· "I don't need a strong ACL on my file, because I (put the file in a hidden location / put the file in a directory with a strong ACL)."
Hopefully, anybody trained to think of security threats will realize that the obscurity of a file's location is no protection. This is particularly true on NTFS, which provides a change journal that tells applications what files on the disk have been changing. You may think that nobody knows where you are creating your log file, but NTFS will happily tell people who ask.
It is also not sufficient to rely upon the ACL on a directory to protect the contents of a file — there are three ways that an attacker can bypass directory security and access a file. First, if the attacker knows or can guess the name of the file, he can just open the file. By default, Windows does not check if a user has permissions on parent directories when opening a file. Second, if the attacker knows the file ID, he can open the file by ID. Finally, the attacker can do the same thing with the object ID for the file.
· "I don't need a strong ACL on my file, because I open an exclusive-access handle to the file."
When you create a file handle using CreateFile( ), you get to specify a sharing mode. This tells the operating system to place constraints on the types of handles that may be opened concurrently with yours. For example, you may choose not to share access with other read handles.
However, the sharing mode is a coarse-grained mechanism for concurrency control; it is not a mechanism to secure access to data. Using sharing modes for security has three problems. First, the proliferation of shadow copy technology within Windows means that, while you may be able to use sharing modes to keep people from reading the current version of a file, there is a high likelihood that there is a read-only copy of the file that is unprotected by sharing modes. Second, there is an inherent race condition when you try to use sharing modes for security: what if the attacker is able to open his handle before you? Finally, if you ever close your handle — for example, if your application AVs — then the data is unprotected.
In short, if you want to secure access to a file, the only reliable way is to place an appropriate ACL directly on the file.
2. Understand how ACL inheritance works
Once you know the ACL that you want to put on your file, and you know to put the ACL on the file and not some other directory, you need to understand how you are applying the ACL to your file. One mechanism for putting an ACL on a file is to use object inheritance. In this scenario, you place your desired ACL on the directory you store your files in, and then mark the directory to have child objects inherit the ACL.
There is nothing wrong with using directory inheritance as the mechanism for applying ACLs to your files. This is probably the most convenient way to apply ACLs to files if your application stores all of its files in a single directory. However, the common misunderstanding of inheritance is that the ACLs automatically apply to any file in the directory. This is not true: the ACLs are inherited only for new files created in that directory. If you move an existing file into the directory, it will retain its ACLs. Therefore, you cannot rely upon ACL inheritance to secure access to files that you move into secured directories.
3. Understand the risks of Delete child access right
For the most part, you rely only on the ACLs on files to secure access to files. However, there is a vulnerability for files that relates not to a weak ACL on the file, but rather to the ACL on the file's directory. If an attacker has Delete child access right for a directory, then he has the ability to delete any file in that directory — even files that he has no access to.
The ability to delete a file is particularly dangerous if it is coupled with the ability to read the file and create new files in the directory; the combination of these privileges is equivalent to Take ownership. Why? Because the attacker can read the data from the file, delete the file, and then recreate a file with the same name and with the same data — only now the attacker is the owner, with implicit full control over the data, and you might not ever realize it.
In summary, the best practices for securing access to a file comes down to:
· Use the ACL on the file, not on directories, to control who gets to access the file.
· Carefully guard who has Delete child access right on directories.