Demands and Link Demands

Demands and Link Demands

I've already shown code that demands permissions to execute correctly. Most classes in the .NET Framework already have demands associated with them, so you do not need to make additional demands whenever developers use a class that accesses a protected resource. For example, the System.IO.File class automatically demands FileIOPermission whenever the code opens a file. If you make a demand in your code for FileIOPermission when you use the File class, you'll cause a redundant and wasteful stack-walk to occur. You should use demands to protect custom resources that require custom permissions.

A link demand causes a security check during just-in-time (JIT) compilation of the calling method and checks only the immediate caller of your code. If the caller does not have sufficient permission to link to your code for example, your code demands the calling code have IsolatedStorageFilePermission at JIT time the link is not allowed and the runtime throws an exception when the code is loaded and executed.

Link demands do not perform a full stack-walk, so your code is still susceptible to luring attacks, in which less-trusted code calls highly trusted code and uses it to perform unauthorized actions. The link demand specifies only which permissions direct callers must have to link to your code. It does not specify which permissions all callers must have to run your code. That can be determined only by performing a stack-walk.

An Example LinkDemand Security Bug

Now to the issue. Look at this code:

[PasswordPermission(SecurityAction.LinkDemand, Unrestricted=true)] [RegistryPermissionAttribute(SecurityAction.PermitOnly, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\AccountingApplication")] public string returnPassword() { return (string)Registry .LocalMachine .OpenSubKey(@"SOFTWARE\AccountingApplication\") .GetValue("Password"); } ... public string returnPasswordWrapper() { return returnPassword(); }

Yes, I know, this code is insecure because it transfers secret data around in code, but I want to make a point here. To call returnPassword, the calling code must have a custom permission named PasswordPermission. If the code were to call returnPassword and it did not have the custom permission, the runtime would raise a security exception and the code would not gain access to the password. However, if code called returnPasswordWrapper, the link demand would be made only against its called returnPassword and not the code calling returnPasswordWrapper, because a link demand goes only one level deep. The code calling returnPasswordWrapper now has the password.

Because link demands are performed only at JIT time and they only verify that the caller has the permission, they are faster than full demands, but they are potentially a weaker security mechanism.

The moral of this story is you should never use link demands unless you have carefully reviewed the code. A full stack-walking demand takes a couple of microseconds to execute, so you'll rarely see much performance gain by replacing demands with link demands. However, if you do have link demands in your code, you should double-check them for security errors, especially if you cannot guarantee that all your callers satisfy your link-time check. Likewise, if you call into code that makes a link demand, does your code perform tasks in a manner that could violate the link demand? Finally, when a link demand exists on a virtual derived element, make sure the same demand exists on the base element.

IMPORTANT
To prevent misuse of LinkDemand and reflection (the process of obtaining information about assemblies and types, as well as creating, invoking, and accessing type instances at run time), the reflection layer in the runtime does a full stack-walk Demand of the same permissions for all late-bound uses. This mitigates possible access of the protected member through reflection where access would not be allowed via the normal early-bound case. Because performing a full stack walk changes the semantics of the link demand when used via reflection and incurs a performance cost, developers should use full demands instead. This makes both the intent and the actual run-time cost most clearly understood.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2001
Pages: 286

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net