Why Do I Still Get an Exception Accessing a File with Full FileIOPermission?


This issue (and its cousin: Why Do I Still Get an Exception Accessing the Registry with Full RegistryPermission?) come up fairly frequently on the newsgroups.  The reasoning is actually very simple.

The exception being thrown in these cases arises from the fact that the CAS model sits on top of the security model provided by the underlying operating system, and does not replace it.  So if you’re running Win9x or one of the Windows NT operating systems with the FAT file system on your drive, you’ll never run into the problem.  On the other hand, if you’re dealing with NTFS or the Registry on NT platforms, you will have to interact with the NT security model.

So, if I’m running as a normal user on a Windows NT machine, even if my assembly is located on the local machine and gets a grant set of FullTrust, I might still get an exception if I try to open c:\boot.ini, since the ACL on that file does not allow access to anyone outside the System account, and the Power Users or Administrators groups.  Similarly, attempting to write a registry key under HKLM while my process is running in the context of a normal user, even with Unrestricted RegistryPermission, will result in an exception.

If you think about it, this makes a lot of sense.  If the CLR were to have some sort of hook that bypassed NT security, and were to say “this managed code was granted FullTrust, let it do anything it wants”, there would be a gaping hole opened up.  Imagine for a minute this were the case.  Now, I can log into a NT machine as guest, write an assembly to my %TMP% folder, and run it.  Since the assembly came from my local machine, by default it will get FullTrust.  And if FullTrust meant that NT security were bypassed, all of the sudden I can make myself and administrator on the machine that I was only a guest on previously.  Clearly that’s not a very good model.

One easy way to tell if you’re running into an issue with CAS or with NT ACLs is to check the type of exception you get.  If there’s a problem with CAS you’ll see a SecurityException.  As of v1.1 of the CLR, failing to complete an operation due to NT security should throw an UnauthorizedAccessException with a message along the lines of ‘Access to the path “c:\boot.ini” is denied.’ instead.

Comments (5)

  1. Eduardo says:

    Estou com o mesmo problema…

  2. John C. Kirk says:

    I’m still a novice at code security, but I thought it was possible/desirable to have an application running with higher permissions than the logged-in user. E.g. you could say "Users can’t modify anything under C:Program Files, unless they use Office Update". I guess you could set up a separate user account for that, and use "Run As", but I would have thought that assigning the higher permissions directly to the application is more secure than having a user account that could be hijacked.

    However, I may have completely missed the point of all this…

  3. georgem says:

    Well, if you would assign permission for the app directly, how will you protect against e.g. guest users – either you have to set a quite complex system with matrix rights per application x per user or you will get completelly open system (difficult to program and even more to maintain, much more vulnerable for security bugs…), where usernames/pwds will be used either for only allowing/disabling access to the machine or not used at all (why, when permissions are set on application level).

  4. Shawn says:

    John,

    It is possible for an application to be running with more permissions than the logged in user, but not if the application was started by that user. The most common case of this is with Windows NT Services, which can run with high trust levels. However, the instance you point out will not currently work. Go ahead and try Office Update when running as guest. You won’t be able to modify files under C;Program Files unless your user account has permission to access those files.

    -Shawn

  5. Shawn says:

    George,

    That’s exactly right, and why its a *good* thing that the CLR security system sits on top of the NT security system. The way it works now is that permissions granted to an application under the CLR are the maximum set of permissions it will ever run with. This is effectively intersected with the set of permissions that NT allows the user to do to come up with the total set of permissions the running instance of the application has.

    -Shawn