- Code Access Security (CAS) is a mechanism that helps limit the access that code has to protected resources and operations.
- In the .NET Framework, code access security performs the following functions:
- Defines permissions and permission sets that represent the right to access various system resources.
- Enables code to demand that its callers have specific permissions.
- Enables code to demand that its callers possess a digital signature, thus allowing only callers from a particular organization or site to call the code.
- Enforces restrictions on code at run time by comparing the granted permissions of every caller on the call stack to the permissions.
- The runtime can make security checks as the program executes, allowing and disallowing the specific types of operations depending on permissions.
- Permission to execute a specific function is not restricted to authentication of the user running the program.
- The runtime also controls execution based on who created the program and whether he is a trusted provider.
- Similarly, you might want to note that CAS also applies security policy based on the location of the executed assembly.
- By default, code installed on the local machine is more trusted than LAN, which is much more trusted than code on the Internet.
- Permissions can be tuned such that partially trusted providers can read and write files from controlled locations on the disk, but they are prevented from accessing other locations for which the provider has not been granted permission.
- Identification of a provider is handled by certificates that are embedded into the program when the provider compiles the code.
Imperative Security
- Before you make the security call, you must initialize the state data of the permission object so that it represents the particular form of the permission you need.
- For example, when creating a
FileIOPermission
object, you can use the constructor to initialize the FileIOPermissionobject
so that it represents either unrestricted access to all files or no access to files.
- Or, you can use a different
FileIOPermission
object, passing parameters that indicate the type of access you want the object to represent (that is, read, append, or write) and what files you want the object to protect.
- In addition to using imperative security syntax to invoke a single security object, you can use it to initialize a group of permissions in a permission set.
- For example, this technique is the only way to reliably perform “assert” calls on multiple permissions in one method.
- Use the
PermissionSet
and NamedPermissionSet
classes to create a group of permissions and then call the appropriate method to invoke the desired security call.
- You can use imperative syntax to perform demands and overrides, but not requests.
- You might use imperative syntax for demands and overrides instead of declarative syntax when information that you need in order to initialize the permission state becomes known only at run time.
- For example, if you want to ensure that callers have permission to read a certain file, but you do not know the name of that file until run time, use an imperative demand.
- You might also choose to use imperative checks instead of declarative checks when you need to determine at run time whether a condition holds and, based on the result of the test, make a security demand (or not).
FileIOPermission fileIOPermission = new FileIOPermission(PermissionState.None);
fileIOPermission.AllLocalFiles = FileIOPermissionAccess.Read;
try
{
fileIOPermission.Demand();
}
catch (SecurityException s)
{
Console.WriteLine(s.Message);
}
Declarative Security
- Declarative security syntax uses attributes to place security information into the metadata of your code.
- Attributes can be placed at the assembly, class, or member level, to indicate the type of request, demand, or override you want to use.
- Requests are used in applications that target the CLR to inform the runtime security system about the permissions that your application needs or does not want.