Question

In this code, I'd like the ReadFileSystem method to be forbidden to Assert a permission on the filesystem.

I expected this will throw at fileIo.Assert(), but it doesn't. Why?

using System.Security.Permissions;
static void Main(string[] args)
{
    var fileIo = new FileIOPermission(PermissionState.Unrestricted);
    var secuPerm = new SecurityPermission(SecurityPermissionFlag.Assertion);
    PermissionSet set = new PermissionSet(PermissionState.Unrestricted);
    set.AddPermission(fileIo);
    set.AddPermission(secuPerm);
    set.Deny();
    ReadFileSystem();
    Console.Read();
}

private static void ReadFileSystem()
{
    var fileIo = newFileIOPermission(PermissionState.Unrestricted);
    fileIo.Assert();

    DirectoryInfo dir = new DirectoryInfo("C:/");
    dir.GetDirectories();
}

Update

Great link here on CAS : http://blogs.msdn.com/shawnfa/archive/2004/08/25/220458.aspx

Was it helpful?

Solution

The subsequent Assert negates the effects of the Deny.

The ability to assert FileIOPermission mainly depends on whether your assembly is trusted. It is not affected by a previous Deny of FileIOPermission. It turns out that it is also not affected by the previous Deny of the Assertion SecurityPermission. This is because SecurityPermissionFlag.Assertion is checked as a link time demand. This is not clearly documented; I found it here.

To force the CLR to not trust your assembly for FileIOPermission, you can use the following at the top of your file following the using statements. When you add this to your file, the assert will not take effect. This affects the entire assembly. There is no finer granularity.

[assembly:FileIOPermission(SecurityAction.RequestRefuse, Unrestricted=true)]

OTHER TIPS

I think you may misunderstand the purpose of Asserting permissions. When you Assert a permission set in CAS, you are effectively saying "I know what I'm doing... I don't care what the permissions are deeper in the stack." That's almost never what you want. You generally want to Demand a permission set. That causes a stack walk, which would find the Deny on the stack and then cause a security exception.

However, since .NET has virtually all the necessary Demands built-in, there's rarely a need to actually Demand anything unless you're doing Asserts (again, that's rare) or you've written your own custom Permission class.

Good question for sure. I ran the code and am a bit mystified too. I just spend a hour or 2 studying the docs and googling but to no avail. Note that MSDN cops out by doing a Demand on the Assertion permission.

Edit: binarycoder's answer pointed me into the right direction.

The Asserion rights are simply not effective in a Full-thrust assembly. Only if you add the following at the top of the file:

[assembly: SecurityPermissionAttribute(SecurityAction.RequestRefuse, Assertion = true)] 

the call to fileIo.Assert() will fail.

But otherwise, trying to Deny() the Assertion permission and the following attribute are totally ineffective (unless you explicitly Demand() the Assertion rights).

[SecurityPermissionAttribute(SecurityAction.Deny, Assertion = true)]
private static void ReadFileSystem() {}

The documentation does state that Assert() 'has some security issues' and the recommendation is to always Demand-before-Assert:

fileIo.Demand();
fileIo.Assert();

but I still have to re-adjust my mindset about applying the principle of least privilege.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top