Control Permissions for Resources
The classes related to controlling permissions and access for resources are live in the System.Security.Permissions namespace. There are a whole lot of permission classes for imperative security access settings, and each of them has its declarative attribute counterpart. There are three major categories of them:
- Code access permissions
- Identity permissions
- Role-based permissions
Code access permissions represents access to a given resource or the ability to perform a specific operation. For example, FileDialogPermission and RegistryPermission are classes which fall into the category of code access permission.
Identity permissions indicates that the code has credentials that support a particular identity. UrlIdentityPermission and GacIdentityPermission (and, as you are surely figured it out, all permission classes which end to IdentityPermission) are identity permissions. They are granted by the CLR based on the available information from the assembly (for example, if the software has a digital signature, it is granted the PublisherIdentityPermission). Identity permissions are in relation with the evidences assemblies provide about themselves. More of it later.
There is only one security permission class for role-based permissions, and I’ve introduced it in the previous post, its name is PrincipalPermission.
You can use these permissions on a
In the rest of this post, I’ll list each permission class, and provide a short introduction of it. At the end, you’ll see a quick description about what do they have in common (how to use them in your code). I’ll start from the back, so role-based permissions first.
- PrincipalPermission: use PrincipalPermission to check to currently executing IPrincipal for a given user name or role. You can pass user name and role into the constructor, and then compare it with the current user. Pass null, and the given category will be ignored.
- AspNetHostingPermission: controls access to public types declared in the System.Web namespace.
- DirectoryServicesPermission: access to System.DirectoryServices classes.
- DnsPermission: access to Domain Name System. By default, only Internet code is denied access.
- EnvironmentPermission: access to environment variables.
- EventLogPermission: access to the event logs.
- FileDialogPermission: the ability of the code to open a dialog for saving/opening files.
- FileIOPermission: read, write, delete, etc. file input/output operations.
- IsolatedStoragePermission: access to the Isolated Storage.
- MessageQueuePermission: access to MSMQ interfaces.
- Odbc/OleDb/Oracle/SqlClientPermission: access to the respective database.
- PerformanceCounterPermission: access to performance counters.
- PrintingPermission: access to printers.
- ReflectionPermission: access to reflection services.
- RegistryPermission: access to the registry.
- SecurityPermission: execute, call unmanaged code, skip verification, etc.
- ServiceControllerPermission: access windows services.
- SocketPermission: connect to a transport address.
- UIPermission: access to the user interface. A minimum requirement for debugging.
- WebPermission: make or accept connections to a web address.
Identity permissions are as follows:
- PublisherIdentityPermission: the publisher’s digital signature.
- SiteIdentityPermission: the web site from where the code is originated.
- StrongNameIdentityPermission: the strong name of the assembly.
- URLIdentityPermission: the URL of the code.
- ZoneIdentityPermission: the zone of the code. Possible values: Internet, Intranet, MyComputer, NoZone, Trusted, Untrusted.
Before using these permissions, let’ s take a look at the SecurityAction enumeration (also lives in System.Security.Permissions namespace). SecurityAction has the following members:
- Assert: the calling code will have access to the resource, even when there are callers higher in the stack who wouldn’t have access.
- Demand: all callers in the call stack must have access to the resource, if not, a SecurityException is thrown.
- Deny: access will be denied to the current resource, even if the callers would otherwise have access.
- InheritanceDemand: the derived class is required to have been granted the specific permissions.
- LinkDemand: the immediate caller is required to have been granted the specific permissions.
- PermintOnly: only the specified permission is granted to the given caller.
- RequestMinimum: the minimum set of permissions required for an assembly to run. Use at assembly level.
- RequestOptional: additional permissions for an assembly. Any permissions not specified here will be refused for the code. Use at assembly level.
- RequestRefuse: permissions not required for the code. Use at assembly level.
Now some examples. The first one restricts access to the Windows directory:
FileIOPermission fiop = new FileIOPermission(FileIOPermissionAccess.AllAccess, @”C:\Windows”);
DirectoryInfo di = new DirectoryInfo(@”C:\Windows”);
This code will throw a SecurityException. But we aren’t fools, and our attackers aren’t neither. For example, assuming the computer name is MYCOMP, the following code will run!
DirectoryInfo di = new DirectoryInfo(@"\\MYCOMP\Windows");
So CAS isn’t almighty, you should be aware of it.
Now grant a permission at the assembly level. Let’s assume that it is crucial for our application to call a web service. Given that, we should add the following code to the AssemblyInfo.cs file, and include the System.Net namespace:
[assembly: WebPermission(SecurityAction.RequestMinimum, Connect=@”http://mySite/update.svc”)]
Permission classes have two more interesting methods. Each of them requires an other instance of IPermission. Intersect returns what the two IPermissions have in common. Only demands that pass both permissions pass their intersection. The other method is Union, which returns an IPermission with the union of the two permissions. So a demand passes the union if it passes either of the two IPermissions.