Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assert Permissions in C#

I'm busy trying to understand the security stuff in c# and I'm struggling to see how Assert works. I'm using .net 3.5.

I made a sample app to try figure this out.

Calling method:

[FileIOPermission(SecurityAction.Deny, ViewAndModify = @"C:\")]
    static void Main(string[] args)
    {
        WriteTest testWriter = new WriteTest();
        testWriter.Test();
        Console.Read();
    }

In a seperate class library I have:

public class WriteTest
{
    public void Test()
    {
        try
        {
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, @"C:\");
            permission.Assert();
            using (StreamWriter sw = new StreamWriter(@"C:\test.txt"))
            {
                sw.WriteLine("testing!");
                sw.Flush();
            }
            Console.WriteLine("Writen to file!");
        }
        catch (SecurityException sec)
        {
            Console.WriteLine("No privileges!");
        }
    }
}

This code executes fine and all. It will write to the file. My question is how exactly does this work? Does this not invalidate the security classes if I can just Assert the permissions I want so that it skips the checks? If I change Assert to Demand it throws an exception.

Is the point of the security classes not to allow me to set permissions so that when I call a third party class I can prevent it from going rogue and doing stuff I don't want it to do? I know if I load the dll in an AppDomain I will get this effect even if the third party DLL does use Assert, it just seems strange that if I call it directly it will work. I've tried reading the MSDN documentation on Assert but I'm finding it hard to understand.

like image 702
David Esteves Avatar asked Feb 05 '12 09:02

David Esteves


2 Answers

Assert() is useful when less-privileged code ("Assembly A") calls more-privileged code ("Assembly B") to perform some task. To carry out that task, Assembly B needs to run code that requires a powerful permission—a permission that Assembly A might not have. So Assembly B first demands a less-powerful permission (the permission to perform the task in the first place) and then asserts the more-powerful permission to actually carry out the task.

For example, suppose a partial-trust Silverlight app wants to make an HTTP request using the System.Net.WebRequest class. Establishing a network connection requires SocketPermission, but this is a powerful, low-level permission that shouldn't be granted to untrusted code from the Internet. So WebRequest demands a less-powerful permission, WebPermission, and then asserts SocketPermission before going on to establish the network connection.

Now, in your particular example, the Assert() overrides the Deny because the class library is running at the same privilege level as the application—both the application and class library are likely running as Full Trust. An assembly can always Assert() any permission in its grant set. To enforce the Deny on the class library, you would have to put the class library in a sandbox.

Note: In .NET 4.0, Deny has been deprecated. From MSDN Library:

Runtime support has been removed for enforcing the Deny, RequestMinimum, RequestOptional, and RequestRefuse permission requests. In general, these requests were not well understood and presented the potential for security vulnerabilities when they were not used properly:

  • A Deny action could be easily overridden by an Assert action. The code in an assembly was able to execute an Assert action for a permission if the permission was in the grant set for the assembly. The Assert prevented the Deny from being seen on the stack, making it ineffective.
like image 151
Michael Liu Avatar answered Nov 10 '22 09:11

Michael Liu


The Assert() method causes Code Access Security (CAS) stop walking the stack on a specific permission check request.

Assert is a method that can be called on code access permission classes and on the PermissionSet class. You can use Assert to enable your code (and downstream callers) to perform actions that your code has permission to do but its callers might not have permission to do. A security assertion changes the normal process that the runtime performs during a security check. When you assert a permission, it tells the security system not to check the callers of your code for the asserted permission.

Using the Assert Method

I think you want Demand()

Of Interest:

  • Security Changes in the .NET Framework 4
  • Understand how permission requests work
like image 21
Mitch Wheat Avatar answered Nov 10 '22 09:11

Mitch Wheat