Reputation: 680
Recently I was debugging a "poof-all-customer-data-is-gone" problem. It did not take much time to figure out that a wrong branch led to a Directory.Delete(customerRoot, true)
line of code. The catastrophic line was written by a regular GUI developer. There are not many lines that can lead to such a disaster. So my question is how to prevent this particular call. (DirectoryInfo.Delete()
is the second one).
Here is my prioritized list of possible solutions
Any other idea?
I will mention that our system has a dedicated service (validated and logged) for file/folder delete.
Upvotes: 4
Views: 723
Reputation: 7449
You can modify the application to not run under full trust. Configure a trust level that restricts access to the physical disk. Take a look at FileIOPermission. Note that this can be configured for specific locations, giving you a fair bit of control.
Update After thinking about this some more, I would also suggest a "nanny test". If you're doing any kind of testing, you can add a test that looks at all the types in your assembly, and checks for calls to any of the FileSystem methods. Any such calls need to be on a whitelist, otherwise the test fails. The project that I am working on uses this, and it provides a lot of value.
Update 2 There was a comment on how to do this type of nanny test. Basically, you need to use reflection to get all the methods, and then look in the IL for the forbidden call. It sounds more complex than it is.
Mechanism to extract specific IL (.NET Intermediate Language) signatures from an assembly
Update 3 There is another, better, way to do this type of nanny test that doesn't directly involve messing with IL. I posted an article on my blog how to do this.
http://datatoknowledge.com/2012/09/10/nanny-tests/
Erick
Upvotes: 1
Reputation: 2347
To "intercept" the call at runtime, you can use the FileSystemWatcher class, but it wont actually prevent the deletion, just let you know it's happened. Preventing the actual deletion is a lot trickier. Windows does not offer Linux's ptrace functionality, so you cannot intercept the system call itself (there is an article about that here but the usability is fairly limited from what I can tell). What others suggest - setting access rights and trust levels - might work, but when you do actually need to delete something and your "deletion service" is just a wrapper around the .NET methods, you will prevent that from working, too.
The other option is to go for third party tools and check this at compile time - this question has just what you need for that, including examples, and there's a lot more tools that can do this (I only use Resharper, but I would imagine it can accomplish the task as well).
However, I dont think thats the point here. Your dev made a mistake, it whacked some customer data and nobody's happy about that. It doesnt mean you need to make a system-wide rule of it and enforce that rule, it means the dev should have tested his or her code better and/or should have used the deletion service you mention (whatever that is). No matter how hard you try, you cant prevent people from doing stupid things. You dont want to spend time and money making fortifications around the Directory.Delete() method only to find out that someone else made a different silly mistake and this particular thing will never be an issue again. Unless problems like this (misusing Directory.Delete() ) are prone to happen more than usual in your system, let it go, concentrate on other things.
Upvotes: 1
Reputation: 1644
You could include a separate Directory Class (and DirectoryInfo) within a globally included namespace - this won't stop someone using System.IO.Directory.Delete, but it is another idea that might help to catch it and put them off, especially if you include an identical dummy function that throws an exception with a message.
Upvotes: 0