Weblog
Mono Security Manager Part III - Using Non-CAS permissions
Are there such things as non-CAS permissions ? Well I surely hope so, code security is fairly new compared to Role-Based Access Control (RBAC) or any arbitrary permission (e.g. time based). But technically the CLR doesn't make much difference of them and most differences are hidden to developpers.
So what are the technical differences between CAS and non-CAS permissions ?
- All CAS permissions classes inherits from
System.Security.CodeAccessPermission. This means they implement both theIPermissionand theIStackWalkinterfaces; - Non CAS permissions don't have to inherit from any specific class but must implement the
IPermissioninterface. The only example in the framework is thePrincipalPermissionclass - a classic RBAC example; - As non CAS permissions do not implement the
IStackWalkinterface they cannot be used toAssert,DenyorPermitOnly(i.e. the stack modifiers). In fact they do not provoke a stack walk at all.
Non CAS permission have been working for a while on Mono. In fact this sample, with a few subtle changes, would work under Mono 1.0.x. The subtlety is that we can now use declarative security syntax (i.e. attributes) instead of using imperative security (i.e. source code).
To be used for declarative security, a permission class must have a corresponding security attribute class
(e.g. PrincipalPermissionAttribute). The attribute class must inherit from SecurityAttribute,
otherwise it attribute will be encoded as a custom attribute (i.e. the security manager won't execute it).
Now just to confuse things all security attributes do not inherit directly from SecurityAttribute
but from CodeAccessSecurityAttribute - even non CAS permissions (note that the class isn't named
CodeAccessPermissionAttribute after all ;-).
The following sample restrict execution of the Execute method to the user named root.
Unlike my two previous blog entries, it doesn't restrict a specific
resource or something specific to the assembly
(i.e. code identity), but the user itself.
Now compile the sample, try to execute it without the security manager, then execute it with the security manager and finally execute it as root with the security manager still enabled...
So the security manager does more then just handle CAS. But CAS is so big that most people don't make any
distinction between CAS and the security manager. As I said before the framework itself doesn't help much in making
a distinction, let's try a variation: Insert a line to disable the SecurityManager just before calling the
Execute method...
and execute it again, as yourself and as root, with the security manager enabled...
and the PrincipalPermission still gets called! It's not a Mono specific behavior but don't trust me just because I wrote
this on the internet, go ahead and try it on the MS framework ;-). The "security manager" is an overloaded keyword in the CLR.
Also note that on Mono it won't work (i.e. it won't get called) if you do not enable the security manager.
This leads to an important feature, supplying the --security to Mono means more than just turning on the SecurityManager.SecurityEnabled property. The reverse is also true, and potentially more dangerous, not enabling the security manager
disable more security than turning off the SecurityManager.SecurityEnabled property!
Q&A
Q - What happens if I use a [PrincipalPermission(...)] in my code and execute it with Mono 1.0.x or before Mono 1.1.4 ?
A - It will be ignored as any type (CAS or non-CAS) of declarative security. In fact it will also be ignore with 1.1.4 onward
if you do not activate the security manager (--security).
Q - Can non-CAS permission be used for LinkDemand (JIT time) and InheritanceDemand (load time) ?
A - PrincipalPermission wouldn't be very useful, but it's still usable. Other custom non-CAS permission could be more useful.
There is much more to say (and do) on CAS but the last three entries covers what's available in Mono 1.1.4, so I'll probably keep quiet on CAS until 1.1.5 is released with even more goodies ;-).
2/23/2005 18:58:29 | Comments | Permalink
Mono Security Manager Part II - Using Code Identity Permissions
Yesterday
I showed a sample which demanded a resource permission, UnmanagedCode in order
to call Environment.Exit. Today I'll do something very similar with an identity permission.
If you have read
Keith's article
then you have seen the difference between the resource (e.g. file, registry, sockets...)
and the identity (e.g. url, hash, zone...) permissions
- aptly named *IdentityPermission. If not the previous examples should be enough
to give you an idea ;-)
The following sample is based on the most commonly used identity permission, at least in source
code, the StrongNameIdentityPermission.
This identity permission allows you to control access based on the presence (or absence) of a
digital signature on the assembly (or assemblies [1]).
As a first step, we need to create a new key pair for this sample. This key pair will let us sign our sample assembly later.
Next we need to extract the public key from the identity.snk file so we can include
it in our application source code.
Now the source code...
Note: You need to replace the incomplete PublicKey property with
the one you generated with the sn tool.
The sample will only allows [2] the Execute method to be executed
if the assembly has the corresponding public key.
Note that I didn't said "if the assembly is signed"! This isn't the identity
permission job to check if the identity is valid (or not). Identities are supplied
by the runtime as evidences to evaluate the security policies - so it is the
runtime job to ensure the evidence are valid before supplying them. This also
means that no cryptographic operation (e.g. signature verification) are required
each time a StrongNameIdentityPermission is being checked.
Now we compile this sample without signing the resulting assembly. We can then execute the sample with and without the security manager.
So the security manager, if active, does it's job not to execute the Execute
method if no public key is present in the assembly.
Now recompile the sample this time signing the resulting assembly and execute the sample (again with and without the security manager).
Note: the /keyfile switch is available for MCS (1.x) and CSC 8.x (fx 2.0).
This means that you must add [assembly: AssemblyKeyFileName ("identity.snk")]
in the sample's source code for CSC 7.x (fx 1.0/1.1).
In this case the security manager, when active, did a stack walk, because the security action
is a Demand, and found out that all assemblies on the stack had the
required StrongName to allow execution of the Execute method.
So far it's very much like using resource permissions, but it's not yet over...
[1] Pitfalls
Code Identity Permissions are rarely used with "classic" Demands (as we do in this sample).
This is because a stack walk requires all assemblies (on the stack) to succeed the security check.
In this case this requires all assemblies to share the same strongname (identity).
This may happens if you use a Zone identity but it's unlikely to be true for most others
- like StrongNames. The reason this sample works is that only one assembly is present on the
stack when the demand is executed by the security manager.
Now that doesn't mean identity permission aren't useful - they just aren't much used with a standard (stack walk) Demand. However they are far more useful when used with LinkDemand, evaluated at JIT time, or with InheritanceDemand, evaluated at load time (both unavailable in Mono 1.1.4 but present in SVN HEAD). Something to blog on later...
[2] Looking forward: Fx 2.0
A very important fact to be aware is that version 2.0 of the .NET framework will be introducing a big change for identity permissions: they will become unrestricted permissions like the resources permissions. Which means that this sample, when executing on 2.0, will work even if the assembly isn't signed!
Why ? Because the application is local, so it is, by default, running at FullTrust. Full trust implies that you have unrestricted access to ressources (in 1.x) and now (in 2.0) that identity permission are unrestricted permissions, unrestricted access to identities.
This means that anyone using identity permissions as a code access control mechanisms for fully trust code (e.g. a plugin system based on strongnames for digital signature and enforced by the runtime/security manager) will loose this feature soon. And yes this also means that any (fully trusted) code can now inherit/override from (InheritanceDemand) or call (LinkDemand) into the class library - so it doesn't just unprotect your code.
Now I may not like it but this isn't as bad as it sounds. There were already ways to fool around such protections. Some (most?) people were putting too much confidence into them (hey! you're still dealing with fully trusted code). Some other (not too serious - even if they don't know it) people were even claiming to have broken .NET security because of this. Conclusion: the code is running at FullTrust so it should be and will now be fully trusted ;-).
Next stop... non-CAS permissions aren't oximorons!
2/22/2005 10:04:00 | Comments | Permalink
Mono Security Manager Part I - Using CAS permissions
Here's the first promised CAS sample for Mono.
As you can see the sample is quite simple - the Loop method denies any request to call unmanaged code.
Either via directly using P/Invoke or by using framework methods that requires the privilege to call unmanaged code.
The later case is being demonstrated in the sample when calling the Environment.Exit static method.
Here's the definition for System.Environment.Exit(Int32):
First line:
The MethodImplOptions.InternalCall indicates that the actual implementation of the method resides in the Mono runtime.
The security manager doesn't enforce any restriction to execute this icall because the type, Environment,
and the method, Exit are both public and because Mono 1.1.4 doesn't (yet) enforce restrictions on calling
runtime's icalls (but this feature is already in SVN for HEAD users).
Second line:
The security manager (if active) will initiate a stack walk to ensure that all callers on the stack have the rights to call
unmanaged code. In this case both the executing assembly (e.g. exit.exe) and mscorlib.dll are in the local
file system and are granted FullTrust. This means that, under normal condition, the call to Exit should succeed.
The definition of the method call.
Now let's compile the sample code and try to execute it without enabling the security manager.
The sample starts by indicating the status of the security manager. In this case (OFF) nothing can stop you from
quiting the application before ending the loop. Type quit followed by ENTER to quit the sample.
While this isn't a big problem when running an application at FullTrust it's more a problem if you are hosting mono inside
your application (e.g. a database server supporting C# stored proc) or if you have a plug-in system.
Next execute again the sample code with the security manager enabled:
In this case (ON) the security manager will stops you from quitting the application directly from inside the loop
(i.e. where the Deny declarative security attribute applies). Type quit followed by ENTER. You
should see the text from the SecurityException thrown from the security manager. Now type endloop followed by
ENTER to quit the sample.
Note that this sample isn't very secure (i.e. don't use that pattern) as the loop is still running at FullTrust - there
are much better way to sandbox code than to use Deny. You will also get the same behaviour (by default) using
MS Framework on Windows. However calling "exit" in a Windows' shell will close the shell - not execute the program -
so be sure to specify the ending .exe in the command line.
Now this sample works because Demand (i.e. stack walks) is functional in Mono 1.1.4 as are the declarative
stack modifiers (e.g. Deny) and most important because I added the proper security checks (either in declarative or
imperative form) to the System.Environment class before the 1.1.4 release. This means that similar cases with
different classes won't work because there is no security permission to protect them (yet)! But nothings stops you
from adding permissions into your own code today ;-)
Next stop... identity permissions!
2/21/2005 08:51:50 | Comments | Permalink
New security features in Mono 1.1.4
Rejoy! Mono 1.1.4 is out and full of new goodies :-)
CAS
The most interesting feature, at least from my point of view ;-), is that Code Access Security (CAS) can now be used with Mono. This is the first version were end-users can see visible progress since CAS first steps last summer.
Mono 1.1.4 supports a new --security switch to enable the security manager - which is responsable (among other things) for CAS.
The security manager allows stack walks, and other security actions, to occurs when permissions are demanded either by the user or the runtime itself.
This is still a work in progress and very few permissions are present at this time in the class library but the core is there!
More details about what you can (and can't) do with CAS next week...
In the mean time, and if you want to learn more about CAS in general, I suggest you read the recent article "An Introduction to Code Access Security" from Keith Brown on MSDN.
New and updated tools
The certmgr tool has been updated to download certificates, including up-to the root certificate if desired.
This can be done from any SSL session (as long as you supply the port number for non-Fx protocol), e.g.
There are a few possible problems (like old root certificates using MD2 in their signature) so be sure to read the man page if it doesn't work.
Other recent security tool additions are caspol.exe to edit Code Access Security policies for Mono (not well tested at this stage) and permview.exe to display the declarative security attributes inside an assembly. The current permview.exe is rather limited but a future Cecil-based version will do a lot of cool stuff.
2/18/2005 16:25:22 | Comments | Permalink
Another one bites the dust
After MD5 last year, it's SHA-1 turn to disappoint us. SHA-1 isn't as good as expected - at 2^69 it's a long way from the advertised 2^80. I guess it's time to review your usage (direct or indirect) of the algorithm.
We're facing an endangered spece when individuals from a spece dies faster than they reproduce. We're sure facing this problem today with hash algorithms. Another analogy is the poor genetic pool, the fact that the SHA-2 family is related to SHA-1. So it's not clear (at least now) how much of the problem the SHA-2 algorithms (SHA-256/224 and SHA-512/384) have inherited.
Not much I can do myself for this problem :-(. Let's hope this news will encourage more people to look for new alternatives...
In the not much category I reopened the SHA-224 support suggestion for framework 2.0 at Microsoft. Please take a few seconds to vote for it. On the bright side support for SHA-224 is already available in Mono.Security.dll (for both Mono and MS runtime users). I'll also update Monodoc with the appropriate warnings...
Addendum: Thanks to the jackson specy for correcting my english ;-)
2/16/2005 12:13:17 | Comments | Permalink
The views expressed on this website/weblog are mine alone and do not necessarily reflect the views of my employer.
