The .NET Permissions Maze

Last week, I introduced the concept of partially trusted, or

semi-trusted, code in the .NET framework. All too often, developers

consciously or by default assume that their code will execute in a fully

trusted environment, leading to weird security exceptions that aren't

consistent between machines. I know that you and I aren't THAT kind of

developer, but how do you write code for partially trusted execution?

One of the keys is to understand the chain of permissions that permeate

your code and all the assemblies it calls. This is not a trivial task.

You can look up a method in the framework documentation, say for the

GetValueNames method of the RegistryKey class, and see in the

requirements section that it requires the RegistryPermission permission

Read in order to call the method. And you're relying on the completeness

of the framework documentation, which it isn't. You can also explore an

assembly with the .NET framework SDK tool ildasm, but that's a hit and

miss proposition.

One way to proceed-for real-world applications that aren't sure to run

in fully trusted environments-is to keep a list of permissions your code

needs as you write the code. Then you can test it in an environment with

only those permissions. Another solution is to set up and design the

application so that the Common Language Runtime (CLR) verifies that it

has the permissions necessary for execution before it ever runs. This

way the CLR will block execution if the code doesn't have the necessary

permissions. You can do this through either imperative or declarative

security. Another method would be to litter your code with

Try-Catch-Finally blocks that trap various

System.Security.CodeAccessPermissions, and perhaps other permission

types as well. The first method is manual, the second puts the burden on

the CLR (where it probably belongs in most applications), and the third

puts the burden on the developer.

Keep in mind that, as I discussed last week, any strongly named assembly

must be marked with the AllowPartiallyTrustedCallersAttribute. If it is

strongly named and not marked with this attribute, the CLR will not run

the code in a partially trusted environment. Period. Strongly named

assemblies are required if they are to be included in the global

assembly cache, and a basic requirement for code that needs to be highly

secure.

This restriction is enforced by the CLR by the placement of a LinkDemand

for Fulltrust on every public and protected member of every

publicly-accessible class in the assembly. The effect of this is that if

the code is not fully trusted, it isn't going to run.

The next couple of weeks I'll talk about imperative and explicit

security.

Top 10 Hot Internet of Things Startups
Join the discussion
Be the first to comment on this article. Our Commenting Policies