how to lock filename - c#

how to lock filename , so windows users can not change File filename .

Two ways:
Use the security permissions to restrict the user from doing so.
Open the file in exclusive mode, denying any operation on it by any other app.
Unfortunately, none of them is fail-proof... for the good of humanity :)

Thank God, this is not possible. You may restrict access to this file, so the user won't be able to access it and thus modify its name, but otherwise you cannot prevent them from renaming files.
One more thing, though...
If the file is continuously open in exclusive mode, nobody else will able to modify it, i.e. change its name... But this mean that some process has to lock it, i.e. windows service. Closing such service or killing the process in other way will release the lock.

Think outside the box - use Alternative data streams.
Hide the filename you want in there & have a background task to locate ads with your data stream and restore the 'correct' file name.
Thats not foolproof either, if the user moves the file to a fat32 volume & back again your ads will be lost.
Think outside the box - write your own file system and install it as an ifs
Think outside the box - don't put your data in a file, put it in a database
Think outside the box - Trust your users
This is what most of us do. Helpful error messages at start-up, graceful recovery, perhaps a file dialogue so the user can choose a filename that suits them for reasons you havn't anticipated.

Related

Delete an "in use" file after no processes reference it

Searched a lot, but without luck - so here goes
My C# winforms application creates temp files which are opened using the default registered application (let's call them viewer apps). Once the user is done viewing those files, I want to delete them.
Currently, I register for an Application.ApplicationExit event, to delete the file. This approach covers most of the situations but not all. Sometimes the user still has the viewing application open while exiting my app, so the success of my File.Delete depends on whether the viewer has opened the file with FileShare.Delete or not - which is out of my control.
This is what I have found so far, but fall short of what I want
FileOptions.DeleteOnClose does not help, since my app will already be closed in some cases and the temp file will still be needed. Also, when I create the file like this: new FileStream(fn, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete, 4096, FileOptions.DeleteOnClose), the viewer apps like say adobe reader & notepad, still complain about file in use by my application The process cannot access the file because it is being used by another process
MoveFileEx with MOVEFILE_DELAY_UNTIL_REBOOT dwFlags works, but it would wait till a reboot to delete it - I would rather have it deleted once the use is done, since reboots can be few and far between and forcing reboots IMO is not the most user friendly approach. On a side note, does windows automatically clear the %temp% folder on restart? Or is there any temp folder that windows automatically clears on restart?
I can write another background process which constantly tries to delete the temp files till it succeeds, but I would like to avoid deploying one more piece of software to accomplish this. It can be done using a windows service or scheduled task or adding command line switches to my existing app and making it run in "delete mode" in background or through task scheduler. All of it decrease my ease of deployment and use along with increasing my footprint on client's computer
In a nutshell, I am wondering if there is any Win32 API or .NET Framework API that will delete a file as soon as there are no processes with open handle to that file?
EDIT:
The information in the temp files are reasonably private (think your downloaded bank account statements) and hence the need for immediate deletion after viewing as opposed to waiting for a reboot or app restart
Summary of all Answers and Comments
After doing some more experiments with inputs from Scott Chamberlain's answer, and other comments on this question, the best path seems to be to force the end users to close the viewer app before closing my application, if the viewer app disallows deletion (FileShare.Delete) of the temp file. The below factors played a role in the decision
The best option is FileOptions.DeleteOnClose, but this only works if all files open before or after this call use FileShare.Delete option to open the file.
Viewer apps can frequently open files without FileShare.Delete option.
Some viewers close the handle immediately after reading/displaying the file contents (like notepad), whereas some other apps (like Adobe Reader) retain such handle till the file is closed in the viewer
Keeping sensitive files on disk for any longer than required is definitely not a good way to proceed. So waiting till reboot should only be used as a fail-safe and not as the main strategy.
The costs of maintaining another process to do the temp file cleanup, far exceeds the slight user inconvenience when they are forced to "close" the viewer before proceeding further.
This answer is based on my comments in the question.
Try write the file without the delete, close the file, let the editor open the file, then open a new filestream as a read with DeleteOnClose with an empty body in the using section.
If that 2nd opening does not fail it will behave exactly like you wanted, it will delete the file as soon as there are no processes with open handle to that file. If the 2nd opening for the delete does fail you can use MoveFileEx as a fallback failsafe.

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

How to make folder uncopyable

I have a program that decrypts a zip file, extracts it to a secret location, and then runs a program in the extracted folder. I would like to ensure that no external program can copy the extract folder to another location (the secret folder is deleted upon program completion).
I have already eliminated Windows Explorer by making my decryption program a "always on top" program that deletes the secret folder if it is killed (by use of another hidden program that the decryption program starts). My concern is that another program could watch the process list, discover the folder location and perform the copy.
Is there a way to prevent programmatic copying of a directory, or if not, of a file?
Look at Directory.CreateDirectory(string,DirectorySecurity)
You'll need to create a DirectorySecurity object that encapsulates the desired permission set. The easiest way is to create a model directory owned by the process' userid with the desired permission sets (e.g., "Only I can traverse this directory or see or even open anything in it."). Once you've done that, use the DirectorySecurity constructor overload DirectorySecurity(String, AccessControlSections) to instantiate a DirectorySecurity object with identical permissions.
Another approach, of course, would be to create the same sort of "model directory" as above and create your "secret" working directory as a subdirectory of that, inheriting the parent's permission set.
As far as securely deleting the contents on disk, look at the question "Shredding files in .NET"
If the information is that sensitive, you should probably be decrypting it into memory rather than disk. But you should be aware that that's not secure either. The recent data breach Target's POS systems suffered was due to custom-designed malware harvesting plain-text credit card and other PCI/sensitive data from process memory.
Well for that purpose you need to set share mode. Not sure about C# solution, but as far as I know in C# you are able to use Win32, so you need to open files in that folder using CreateFile and set dwShareMode to zero.
Also if you want to delete all the stuff after program terminates, you can use FILE_FLAG_DELETE_ON_CLOSE flag.
So as I mentioned, not sure if it is easy to do this using C#, but you can always trust C++, it lets do the stuff in lower level.
The file system is always public, when run from a user context.
You could always attempt to extract the 'folder' to a binary stream - and create a raw, binary file on the file system, that would have no obvious meaning - e.g. make your own temporary "file system"
Short answer: you can't.
Do note that hiding a window / displaying a window always on top are very weak protections, it's really easy to change that from another process.
Also do note that you always can suspend processes instead of terminating them, so it's also easy to prevent any logic such as "if you're killed, then I do XXX" to execute
Best thing you could do is create a user account and restrict rights to read your files/directory to only this account. Of course, admin will still have access to it.

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.

General file attribute to identify file without its path or even name

I am working on an application that keeps track and uses files stored on the file system. Users are allowed to open, create, delete and move files in the file system. Meanwhile my application is not constantly running so I can't keep track of all changes real-time. Afterwards my application has to find out what file is whom (i.c. as identified in my application).
The most preferred solution for the users is that the application solves every change itself. Each user-interaction is less preferred.
One of my ideas was to use an attribute of a file and assign a key-value to it so when it has been identified once, it can always been recognized afterwards. But I don't know if there is such an attribute. This article didn't give much hope: There is in Windows file systems a pre computed hash for each file?.
Does somebody know if there is such an attribute I can use? And how can I used it in C#?
Is there anyone who is running up against this problem? And how did you solve it?
I'd like to hear good suggestions.
regards, Jaap
If your files don't leave NTFS, this is easily achievable by alternative data streams, where you can store your data along with files. This is more-or-less good article about ADS: http://www.flexhex.com/docs/articles/alternate-streams.phtml
There is another suitable method - it's very efficient, but also very complicated to use, it requires quite good knowledge about NTFS internals - USN Change Journal; see http://msdn.microsoft.com/en-us/library/windows/desktop/aa363798.aspx. With USN Change Journal, you can "get" very efficiently all files that were changed (even all change events) within specified time period.
Nevertheless, if your files leave NTFS realm, e.g. if it's copied to FAT32, contents of ADS is lost.
Relying on a File attribute is "dangerous" in that some user could alter the attribute while your program isn't running. This could lead you to believe that a certain file is (or isn't) tracked by the program while it really isn't.
I would suggest to keep track of the files in a database, XML, or some other file. When your application starts you read the file/db and check for new/deleted/editted files.
You could store a Hash of the files to find out if a file has been moved/editted. Keeping track of files that are moved AND editted is going to be pretty difficult. (I have no clue how you could achieve it)
PS: Have you considered making your application a Windows service? Having the file-management running in the background no matter if the GUI part of your application is running or not?

Categories