RequestOptional and RequestRefuse
The other day Eric Wilson asked how to ensure his code never ran with FullTrust. I replied that the "best" way was to refuse permissions you didn't want, and then Nicole Calinoiu replied that maybe requesting optional permissions was better.
Nicole is right -- requesting optional permissions is the "better" way to do this because you are "white listing" the permissions you need, not "black listing" the permissions you don't need, and from a security perspective white listing is always safer. The idea is that you do know what permissions you do need (it's a fixed set, determined by you) but you don't know all the permissions you don't need (it's a potentially infinite set, determined by the CLR and any 3rd party code installed on your system).
The trade-off, of course, is that white listing tends to be harder to manage then black listing, which is why most security measures use black lists even though they are less secure. The idea here is that users prefer functionality over security, and so it's better to assume that all unknown entities are "safe" and let them get their job done (with some amount of additional risk) rather than have them get frustrated and just turn off the system altogether (a really secure system that is turned off is much worse than a somewhat-secure system turned on!). For example, think of a virus scanner that blocks "known bad" code rather than allowing "known good" code, or an e-mail client that blocks "known bad" file extensions rather than allowing "known good" file extensions. How many people would leave their virus scanner or e-mail attachment blocker on if it didn't let you get any work done?
So, back to the point at hand, if you have some code that does various privileged things (read a database, display dialogs on the screen, etc.) but you know you never need to access the file system, maybe it is easier for you to just refuse FileIOPermission and be done with it. Yes, you take on some risk that somewhere, somehow your code can be tricked into doing bad stuff with (eg) the Registry, but if the rest of your code is well written it is unlikely.
On the other hand, if you have some code that only does one privileged thing (like display a message box) it is probably easier to simple request UIPermissionWindow.SafeSubWindows and be done with it. Now you will be secure against any potential luring attacks, but if you later decide to add more functionality to your application you may have to go back and re-visit your requests (although some of the new tools in Whidbey should help here -- argh! no links for permcalc.exe).
One thing to note is that RequesOptional will always grant you Execution (permission to execute), even if you don't ask for it. You'd be out of luck otherwise ;-)
Thanks Nicole!
Comments
- Anonymous
July 01, 2004
I am having a hard time figuring out what is the true intent of your post. It appears so much like you are saying that non-.NET apps are insecure, dismissing pretty much all applications out there.
I am sorry but the operating system right now grants access by default as a consequence of the inability of MS to engineer an OS which would be useable without admin rights. Whenever you install a third party, the same story again. So what now, will you pretend that all third parties are insecure, and that developers are responsible for that ? What is the true intent of that, even more integration/coupling with the OS? - Anonymous
July 01, 2004
Stephane, I am sorry but I don't understand your comment. The intent of the post was to point out that yes, requesting optional permissions is a more secure way of writing code than refusing permissions, but that it is hard to manage.
This post isn't about 3rd party software being insecure, or about non-.NET apps being insecure, or about running on Windows with non-admin privileges.
If there is something else you would like me to address, please post again. - Anonymous
July 01, 2004
The comment has been removed - Anonymous
July 01, 2004
Thanks for the post Peter. This helped me a lot. - Anonymous
July 01, 2004
No worries. Glad someone liked it ;-) - Anonymous
July 02, 2004
A sample of the "best" way to implement this would clear things up for me... - Anonymous
July 03, 2004
The comment has been removed - Anonymous
July 05, 2004
It's just my opinion ;-). In a well-managed development cycle that has thought about security from the start, it might very well be easier to go with RequestOptional. But for customers trying to ship a product (or just customers who want to "do the right thing" but don't have enough time or resources for a thorough analysis -- remember not all code is shrink-wrapped, sold-to-the-public code; much of it is internal-only LOB code) refusing a few choice permissions that you know you don't need is better than nothing.
Either way, you still have issues though where you need a permission one day, but then you change the design and you don't need it the next day (and who is going to update all the permission requests?). And if you are really going for "least privilege" then you have to be very fine grained, down to the exact files / reg keys / database tables / etc. you want to manipulate.
This is where tools come in, such as the permcalc tool in Whidbey. It's just too much work to expect the average developer (even a security-consious developer) to get it right all the time.
Strictly speaking, just saying "I want to read/write the temp directory" is not good enough if you only need to read/write one (or ten or even one hundred) files out of it. And often times you don't know ahead of time what requirements you have (eg, you create a temp file with a random name supplied by the system; there's no way you can add a declarative attribute requesting the right permission in that case).
Also it should be noted that even without any attributes, your code is unlikely to be lured into doing something really bad. The two most likely avenues for attack are LinkDemands that you are silently (and unknowingly) satisfying, or delegates that are being used for nefarious purposes (which is mitigated by not having "normal" methods that match delegate signatures).
I am by no means saying that refusing permissions is a bad idea; just that you aren't automatically insecure because you failed to refuse / opt-in to any permissions.
Basically, as always, it comes down to risk analysis. Cost-benefit trade-offs.