Specify Assembly Permission Requirements

Specify Assembly Permission Requirements

Requesting permissions is how you let the .NET common language runtime know what your code needs to do to get its job done. Although requesting permissions is optional and is not required for your code to compile, there are important execution reasons for requesting appropriate permissions within your code. When your code demands permissions by using the Demand method, the CLR verifies that all code calling your code has the appropriate permissions. Without these permissions, the request fails. Verification of permissions is determined by performing a stack-walk. It's important from a usability and security perspective that your code receives the minimum permissions required to run, and from a security perspective that it receives no more permissions than it requires to run.

What's a Stack Walk?

Stack walks are an essential part of the security system in the .NET runtime. Before allowing access to protected resources, the runtime environment will verify that all functions calling code that is attempting to access a resource have permission to access the resource. This is called walking the call stack or simply a stack walk.

Request Minimal Permission Set

Requesting permissions increases the likelihood that your code will run properly if it's allowed to execute. If you do not identify the minimum set of permissions your code requires to run, your code will require extra error-handling code to gracefully handle the situations in which it's not granted one or more permissions. Requesting permissions helps ensure that your code is granted only the permissions it needs. You should request only those permissions that your code requires, and no more.

If your code does not access protected resources or perform security-sensitive operations, it's not necessary to request any permissions. For example, if your application requires only FileIOPermission to read one file, and nothing more, add this line to the code:

[assembly: FileIOPermission(SecurityAction.RequestMinimum, Read = @"c:\files\inventory.xml")]

NOTE
All parameters to a declarative permission must be known at compile time.

You should use RequireMinimum to define the minimum must-have grant set. If the runtime cannot grant the minimal set to your application, it will raise a PolicyException exception and your application will not run.

Refuse Unneeded Permissions

In the interests of least privilege, you should simply reject permissions you don't need, even if they might be granted by the runtime. For example, if your application should never perform file operations or access environment variables, include the following in your code:

[assembly: FileIOPermission(SecurityAction.RequestRefuse, Unrestricted = true)] [assembly: EnvironmentPermission(SecurityAction.RequestRefuse, Unrestricted = true)]

If your application is a suspect in a file-based attack and the attack requires file access, you have evidence (no pun intended) that it cannot be your code, because your code refuses all file access.

Request Optional Permissions

The CLR security system gives your code the option to request permissions that it could use but does not need to function properly. If you use this type of request, you must enable your code to catch any exceptions that will be thrown if your code is not granted the optional permission. An example includes an Internet-based game that allows the user to save games locally to the file system, which requires FileIOPermission. If the application is not granted the permission, it is functional but the user cannot save the game. The following code snippet demonstrates how to do this:

[assembly: FileIOPermission(SecurityAction.RequestOptional, Unrestricted = true)]

If you do not request optional permissions in your code, all permissions that could be granted by policy are granted minus permissions refused by the application. You can opt to not use any optional permissions by using this construct:

[assembly: PermissionSet(SecurityAction.RequestOptional, Unrestricted = false)]

The net of this is an assembly granted the following permissions by the runtime:

(PermMaximum (PermMinimum PermOptional)) - PermRefused

This translates to: minimum and optional permissions available in the list of maximum permissions, minus any refused permissions.

Imperative vs. Declarative Permissions

You'll notice the code examples reference assembly-level permissions in square or angled brackets for C# and Visual Basic .NET, respectively. These are called declarative permissions. You can also employ imperative security by creating permission objects within your code. For example, new FileIOPermission(FileIOPermissionAccess.Read, @"c:\files\inven- tory.xml ).Demand(); will raise an exception if the code is not granted the permission to read the XML file.

Make sure your code catches any such exceptions; otherwise, it will halt execution.

There are advantages and disadvantages to each method. Declarative permission is good because it's easy to use and spot in code. Declarative permissions can be viewed with the Permissions View tool (permview) use the /decl switch to help with code audits/reviews. Changes in control flow don't circumvent your check inadvertently, and they can be applied to entire classes.

The major declarative drawback is the fact that the state of the permission must be known at compile time.

More Info
You can determine an assembly's permission requests by using caspol a resolveperm myassembly.exe, which shows what kind of permissions an assembly would get if it were to load, or by using permview in the .NET Framework SDK, which shows an assembly request an assembly's input to the policy which may or may not be honored.



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