.NET Imperative Security

The last couple of weeks I've been discussing partially trusted code in

the .NET framework. Last week I talked briefly about imperative and

declarative security, two ways of ensuring that your code has the

permissions it needs to run. This week I'll talk about imperative

security, and next week I'll cover declarative security.

For most of these examples I'll use access to the Windows registry. Most

registry access requires different forms of RegistryPermission, one of

many permission types in .NET.

Imperative security in .NET uses explicit method calls in your code to

assert the permissions that are required for a particular procedure to

run. There are several ways to do this, depending on the type of

permission and the actual permissions required for that block of code.

One of the easiest ways is to instantiate a new RegistryPermission

object, passing in the constructor the type of permission or access

needed. For example, if the code needs to create or manipulate

AppDomains in the CLR, you could execute this VB.NET code to demand that

permission (the C# code would be very similar):

Dim sp As New

SecurityPermission(SecurityPermissionFlag.ControlAppDomain)

sp.Demand()

If the code has this permission, the procedure continues executing as

normal. But if it doesn't have that permission, a SecurityException

would be raised and execution halted. So you'll normally want to enclose

these kinds of statements in a Try-Catch-Finally block and gracefully

handle the error.

You can also request a specific permission for a particular action, such

as the ability to create a new registry key. In this case, you need a

RegistryPermission for creating a key. This code accomplishes this kind

of check:

Dim rp As New RegistryPermission(RegistryPermissionAccess.Create)

You can also define multiple permissions required by the code. Say that

your code needs to create, read, and write registry keys. For this,

instantiate a new RegistryPermission with a PermissionState of None, to

create the base permission object, then add the additional permissions

required:

Dim rp As New RegistryPermission(PermissionState.None)

rp.SetPathList(RegistryPermissionAccess.Create,

"HKEY_CURRENT_USER\Software")

rp.SetPathList(RegistryPermissionAccess.Read,

"HKEY_CURRENT_USER\Software")

rp.SetPathList(RegistryPermissionAccess.Write,

"HKEY_CURRENT_USER\Software")

rp.Demand()

There are various types of actions you can take here. Demand() means

that you will get a SecurityException if callers higher in the call

stack have not been granted this permission. Assert() asserts that

calling code can access the resource identified by the current

permission through the code that calls this method, even if callers

higher in the stack have not been granted permission to access the

resource. And Deny() prevents callers higher in the call stack from

using the code that calls this method to access the resource specified

by the current instance.

You can also dynamically check permissions at runtime. For example, say

that code needs to create, read, or write a registry key based on some

program logic. The code below shows one of many ways to code a method

that adds the needed permission check, depending on the actual request.

Public Sub AccessRegistry(ByVal rk As RegistryKey, ByVal sKey As

String, ByVal action As RegistryPermissionAccess)

Dim rp As New RegistryPermission(PermissionState.None)

rp.SetPathList(action, rk.Name)

rp.Demand()

Select Case action

Case RegistryPermissionAccess.Create

rk.CreateSubKey("Third Sector Technologies")

Case RegistryPermissionAccess.Read

Dim sk As RegistryKey = rk.OpenSubKey(sKey)

Dim sValue As String = sk.GetValue("Floyd")

Case RegistryPermissionAccess.Write

Dim sk As RegistryKey = rk.OpenSubKey(sKey)

sk.SetValue("Floyd", 1)

End Select

End Sub

Call this code like this:

Dim rk As RegistryKey = Registry.CurrentUser

AccessRegistry(rk, "Third Sector Technologies",

RegistryPermissionAccess.Create)

One additional step you might need to take is to check that the code has

permission to access a particular hive or branch in the registry, since

every key can have its own permissions.

Insider: How the basic tech behind the Internet works
Join the discussion
Be the first to comment on this article. Our Commenting Policies