FileSystemWatcher surpassing file system permissions - c#

While experimenting with FileSystemWatcher, I've found out that it somehow surpasses my user account's permissions to files and folders, and will raise change events with information about what has changed in files and folders that you don't even have access to.
I have two questions about that:
1) Why does this happen ?
2) Is this a problem in the AD configuration ? how do I fix it ?
3) Is there any way to gather these files, or even create a FileSystemInfo of them to get more info about the files (not only the changes made on them) ?
As far as I've tried, only the FileSystemWatcher immune to the restrictions, I can't run any other thing over it, here's a list of what I've tried:
File.Exists
Directory.Exists
FileInfo instance on found files
DirectoryInfo instance on found files
File.Copy
File.Delete
Update: Tried helge's solution, with somethin similar to what he's sugested, not through windows' api, but through the command prompt:
robocopy /B \myserver\folder c:\somefolder
Best command name ever.
You can check through robocopy that /B stands for "backup mode", which is what helge's suggested that would be the cause to this security surpassing.
I'll try anything, I want to find out what exactly causes FileSystemWatcher to be able to watch folders I do not have permission to open. Knowing why, I want to learn both how to block FileSystemWatcher, and how to gather found files.
I'd make a survey if I was with my personal account. Please, can someone help me ? I'll write a blog post about the solution, among other things that might help anyone with the same doubt in the future.

According to this answer on SO the FileSystemWatcher is based on the API function ReadDirectoryChangesW. If that is true it explains the behavior witnessed by you - and why that is not a security hole.
As documented on MSDN ReadDirectoryChangesW needs the privilege SeBackupPrivilege (which is requested by the parameter FILE_FLAG_BACKUP_SEMANTICS to CreateFile). If a file is opened in that mode, the returned handle grants full access to the file, circumventing access checks. This feature is designed for backup programs that need to be able to read everything on disk regardless of permissions.
This is not a security hole because the privilege SeBackupPrivilege which is required for this to work is by default granted to administrators only. Administrators, and in fact anyone with physical access to a machine, are always capable of taking control of and reading every file - unless it is encrypted.
As to which functions can be used to access files in backup mode: There is at least BackupRead for reading. Enumeration is easily possible with FindFirstFile/FindNextFile. Of course this requires the real Windows API, not the crippled .NET file system functions.

Related

.NET Directory.Move results in Access to path is denied with network paths

I know there are a bunch of these questions already but none of the ones I found depict the scenario I have.
So what I want to do is to
move a directory via Directory.Move. Both source and destination are on a file server in the same network so both paths are network paths (starting with \\SERVER rather than a drive letter).
The application that‘s supposed to do that gives me an „UnauthorizedException: Access is denied“. Because it‘s confidential I can‘t show the log or code.
But I tried to reproduce it by simply calling Directory.Move via PowerShell ([System.IO.Directory]::Move()). There I receive the same message. Access to path X is denied. Nothing more.
This error appears with any user context. An admin, an admin with „run as admin“, the user of the application and the user of the application with „run as admin“.
Manually moving these directories works without a problem.
Creating a directory with Directory.CreateDirectory works too. But moving the newly created Directory results in the same error.
Executing these commands on the file server works just fine if using the local path. Using the network path (still on the actual fileserver, though) results again in the Acces is denied error.
Could it be, that the issue lies within the path rather than the directory? The permissions are all correct and set (as said, manual operations work). Are there any workarounds?
I really don‘t know what to do. I‘m the only developer at this company and the rest are network engineers and can‘t help
me either.
There are a number of things that could be causing it to deny access and it would be hard to point you in the right direction without seeing your code. But here are 2 scenarios that might help you.
Scenario 1 - The filepath you are using is in the wrong format, Usually I have had a access denied because the format of the network filepath was actually wrong. I would recommend looking up examples of how you should pass the filepath. Also have a talk with your network engineers and ask them about the rights that have been setup for that filepath.
Scenario 2 - You might be passing a filepath when you also need to specify a name. Now I dont have all the details but I also had issues in the past using the Directory.Move function where I actually had to specify a filename to move it to. You do this by just adding the file and extension to the end of the target path to copy to.
If you could post some more information I might be able to point you in the right direction but this is what I can think of for now. I hope this works for you or atleast brings you closer to an answer. Good luck!
*Edit: It looks like I am wrong on the scenarios, Have a look at this link Can you move a file/folder across a network share in .NET?
You will have to first manually create the filepath and then copy all the files into the new filepath you have created. It seems like Directory.Move has problems when different machines are used.

C# - Locking folders from being edited

i'm making a small project. it's Windows Form Application. i got some sources in a folder (C:/sources). When my program runs, it uses sources from the folder. Currently i can edit the folder by windows explorer, it can cause errors for my program. So i want to lock the folder (C:/sources) from being edited/renamed/deleted when my program runs. How to do so?
EDIT;
Is it possible to show a message like this when user has tried to edit the folder:
"the action cannot be completed because the folder or a file in it is open in another program"
the program that we are talking about is mine..
There are a couple of approaches that you could venture and they vary in difficulty of implementation. It all depends on how important this task is for you. But, before discussing these options; can't you embed those resources in your WinForms application instead? If this is not an option then you can do one of the following:
Write a device driver that can prohibit the access of such resources if your application is running. There are fallbacks to this approach. For example one can impersonate your application by having the same name. But, am not getting in to too much details in trying to break any approach as I am trying to address possible solutions to the current problem. There are different types of drivers that you can consider. Probably the simplest form of this approach would be to implement a mini-filter driver.
Hook certain API's like CreateFile(), NtCreateFile(), ZwCreateFile() although there are many ways to circumvent such mechanism of defense. But, again we are only venturing what you can do to address this constraint of yours.
Open these resources directly from your application and lock it exclusively. For example:
File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None);
as this will result in people getting the message that you desire if they try to open the file.
Maybe you can give more information on what these resources are and we can help you determine which is the best way to protect your files in a reasonable fashion?
Although I don't believe it's the best idea to have files that are critical to the application in a open area like the C: drive, I would look into NTFS file permissions and set the folder to read only, but this wont stop administrative users
See these two posts
restrict access to folder outside of program c#
Setting NTFS permissions in C#.NET

What are security issues in creating file

I am writing log for my application at a path saying :-
"C:\Folder1\Folder2\Myfile.txt" (Configurable)
if this file does not exist I am creating folder structure and file inside my code(If there is no C drive I pop up a message saying log directory doesnt exist).
In code review a colleague said that I should not create folder and files using code rather should ask the client to create the file and only perform write operation on this file.
He says there are security issues with this but not sure what, so I thought of posting it here.
Please help me deciding whether I should create file if not exist or ask the client to create on every installation.
What are the security implications with the first approach?
The write issues are that the user trying to create in the C root folder, may not have permissions to create it there. Never assume the user is an admin always.
Also this is the problem with windows' UAC which will be a problem.
Yes there could be issues. Your program will most likely run under the interative user account and therefore be subject to any UAC conditions imposed on it.
One approach, if this is just a log file, would be to use a temporary file, so use:
http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx
This should be created in a an area local to the logged on user that should allow writing of files.
The security issue i see is the ability of your web application to access and write the files inside the directory (configurable, as you mentioned).
To verify the the access by checking the permissions given to the account under which your apppool is running
or through code see this
No code is inherently unsafe. This all depends on how rest of your code looks like, but as a general rule of thumb you should limit which files your application can access and how it can access them. Limit this as much as possible, without damaging your applications functionality.
Security vulnerabilities which may come from this is allowing user to read file which he shouldn't read, or write to an important file and damage it that way. For example, if file path is being created using user input, user may modify the path so that he accesses file which is not allowed to access.
If you create a path like so:
string filePath = "c:\\mysafefolder\\" + fileName;
and user enters a relative path, for example ..\Windows\Passwords.txt he will effectively gain access to c:\windows\passwords.txt.
If you configure your application to block access to any part of file system except mysafefolder, this attempt to read a secret file will fail.
This is just an example of what might happen, and why it is a good idea to limit your application permissions. Your code might be perfectly safe at this point, but limiting permissions is thinking ahead.

How to give Create, Read and Modify permissions to all users for a file created by my application in C:\ProgramData?

My application basically creates an XML file in C:\ProgramData\MyAppFolder and dumps config settings in it.
I need to allow even standard users to have permission to add or delete settings to these config files. Right now I see that standard users only have read/execute permission but not "Full Control".
I've seen other questions being answered with ways to modify permissions to that particular folder but I don't want to change the default permission level, since it might be reset by a system admin.
If C:\ProgramData can't give that access to all users, is there any folder that best suits the needs of application?
EDIT:
My initial question might be misleading. I don't want to give rights to users, but rather allow the application to modify the XML file when it is run by all users.
DECISION:
I think changing the permissions while creating the folder in ProgramData is the only option.
And if that's not possible, CommonDocuments is the way to go.
Thanks Eve.
I would use a folder in the Environment.SpecialFolder enum.
Example:
var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
Assuming you have an installer for your application, your installer can create a subfolder in the common appdata directory (aka C:\ProgramData) which your application will have read/write access to. Depending on your choice of installation technology you can set the permissions on that folder as well, although that may be overkill. I know with WiX basically all you have to do is a per-machine installation and make sure that sub folder gets created.
Users should not be allowed to write arbitrary data to this directory. This is equivalent to regular users being able to modify the C:\Users\AllUsers directory. If users need to be modifying this directory you have serious design flaws and should reconsider this approach. What should happen is the users are given GUI interface to interact with that manipulates these values behind the scenes without giving them direct access, similar to how getters/setters work in most programming languages. Needless to say it is a very large security hole when regular users can corrupt a system for other users.
UPDATE
I don't want to give users direct access to the file. My question
might have been misleading. I want to allow the program to have full
control on the file even when it being run by all users. I'm actually
doing this: "users are given GUI interface to interact with that
manipulates these values behind the scenes without giving them direct
access"
This article which has far too much information to post here, will provide details on remaining secure as to not leak permissions. The first thing you want to do is make sure that your application user is in its own group and cannot login/have any special permissions. What you can than do is have this group added to the directory with write permissions, which would allow this application to perform these tasks. If that is not possible you will need to work within UAC to not break the security of the system as is detailed in the article above.
Second Update
Thanks for the link. Any suggestions on some other folder which can do
the job, rather than messing with the permissions?
Sure you can write it into the directory where the application is written to, i.e. C:\Program Files\Some Awesome Program, this keeps everything in one place, and you only have to worry about your user/group and anything that the person who installed it has allowed for. It also prevents other people from messing with it unless of course they are administrators.

Acquiring the access privileges of an active user

I have a search algorithm that tries to resolve the location of a directory on a local drive. The directory obviously will need to access other directories present on the system if it is searching for a sub directory of one of those. However in doing this I keep getting the UnauthorizedAccessException.
I would like to provide the search mechanism the access privileges of the active user when it is run, how can I achieve this.
In most cases, the correct answer is that you shouldn't.
Your algorithm should catch the UnauthorizedAccessException, accept that it won't be allowed to navigate further down that folder, and act like the folder is empty.
That means that sometimes you will get an answer that a directory you are looking for doesn't exist when it technically does exist. That's OK. It's the way it's supposed to be. If you don't have permission to it, it doesn't exist for you.
Folders protected under some other users' rights are "private". A program that "Joe" runs is not supposed to look at the folders that belong to "Mary". That's the whole point of permissions.
There are very few controlled exceptions to the rule. Notoriously, Disk Backup and Anti-virus applications need to be able to navigate the entire disk, regardless of folder permissions. They do so by setting up a service that runs under a highly privileged account (maybe "SYSTEM", maybe something else). It will likely be an account that holds the SeBackupPrivilege.
You can do that for your program, if you really need to scan the whole disk, but for most application scenarios you really shouldn't. Only a machine-wide maintenance application like an anti-virus or backup program should be given that kind of authority.
It's not that it's "overkill"; it's that it's "wrong". It does not play by the rules.

Categories