'Best practice: Write files to C:\ProgramData only readable by administrators
I am working on a program that runs as a service and needs to keep some dynamic files. I have decided to create a folder in %ALLUSERSPROFILE%\MyFolder, i.e. C:\ProgramData\MyFolder and put my files there (in subfolders).
The data in the files can be sensitive, so it is important that only administrators can read them, not normal users.
So far, I have just created C:\ProgramData\MyFolder during installation using the CreateDirectory API and specified a restrictive Security Descriptor. All the files and folders I have created have then inherited this Security Descriptor and it seems to have worked fine.
However, I suspect this is not really secure: I suspect an evil user could create the folder C:\ProgramData\MyFolder before my application is installed. He could make himself owner of this folder and then set permissions as he sees fit.
So what should I do to avoid this problem?
I could try to call SetNamedSecurityInfo on C:\ProgramData\MyFolder during installation if the folder exists. But it looks somewhat hard to get that done right. For example, SetNamedSecurityInfo takes a security descriptor in another format than functions such as CreateDirectory. And there are a lot of flags that seem to control inheritance in various complicated ways.
I could try to delete C:\ProgramData\MyFolder and everything contained in it during installation and then recreate it. But it seems pretty invasive to me to just delete an entire subfolder regardless of its content.
I could create all my files in C:\ProgramData\MyFolder and subfolders with CreateFile using the CREATE_ALWAYS flag and with my restrictive security descriptor. In this way I will not rely on inheritance. However, it seems somewhat inelegant: What if an administrator wants to give everybody read access to C:\ProgramData\MyFolder after my program is installed? That will not be possible since my program rewrites files regularly.
I will appreciate any guidance!
Solution 1:[1]
Calling SetNamedSecurityInfo is not harder than CreateDirectory, the basic security descriptor members are the same, it just wants them as separate parameters. Given a SECURITY_DESCRIPTOR intended for CreateDirectory, just call GetSecurityDescriptorDacl to get the DACL pointer etc.
There is also SetFileSecurity and it just takes a SECURITY_DESCRIPTOR as the input. This function might only follow the NT4 DACL rules so calling SetNamedSecurityInfo is probably the best option.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Anders |
