My application works from my local machine, but throws a SecurityException when I move it to a network share

Programs that run on the CLR use something called code access security (CAS). CAS is different from traditional security systems in that it assigns trust to code rather than users. To do this, the security system gathers a set of evidence about every assembly it loads.  This evidence is then compared against the security policy, and a permission grant is generated. A good reference CAS can be found here:
 
https://msdn.microsoft.com/msdnmag/issues/01/02/CAS/default.aspx
 
One of the pieces of evidence that the security system gathers is the security zone that the code is running from. When you run the code from your local machine, this will be the MyComputer zone, but when you run it off of a server, or even a network share mapped to a drive on your machine, it will be the LocalIntranet zone.

By default any code that is run from the MyComputer zone will get a permission set of FullTrust (unrestricted permission to do anything it pleases). However, by default, there is a more restrictive permission set given to LocalIntranet assemblies.

There are three ways to make an application that works from the MyComputer zone work from the LocalIntranet zone.

  1. Determine what permissions are being demanded that are causing your application to throw, and try to modify your application to not require these permissions any more. The SecurityException that is being thrown should tell you which demand
    failed.
  2. Give all the assemblies in your application a strong name, and modify the security policy to trust this strong name. (recommended)
  3. Modify the security policy to fully trust the LocalIntranet zone. (generally a bad idea)

In order to modify the security policy to trust a specific strong name, you'll first need to sign the assemblies in your application, and give them a strong name, you'll need to generate a strong name key pair using the sn.exe tool:

  • sn -k mykey.snk

Once you have this key, you'll need to make sure your assemblies are signed with it.  The easiest way to do this is to add an AssemblyKeyFileAttribute to your assembly.  In the above example, my attribute would be [AssemblyKeyFile("mykey.snk")].  Note, if you are using Visual Studio to build your projects, you'll need to put a path relative to the location VS puts your binary assemblies.  So if your assembly is built to bin\Release, you'd need to use "..\..\mykey.snk".

In addition to a signature, assemblies need to have a version number to have a strong name.  Make sure your assemblies have the AssemblyVersionAttribute on them if you are going to use a strong name.  You will also need to make sure that you give all of the assemblies in your application the strong name signature.

If you don't sign your assemblies, and instead decide to modify your security policy to fully trust the Intranet zone, be aware that any applicaiton that somebody puts on a network share will be able to run unchecked on your local machine.  Since this is a pretty large security hole, it is generally recommended that you trust strong names rather than zones.

The easiest way to modify your security policy is by using the Microsoft .NET Framework Configuration utility from the control panel.  You can also run this tool from the command line by running mscorcfg.msc.

  1. Expand the Runtime Security Policy folder
  2. Expand the Machine policy level
  3. Expand the Code Groups folder

To modify the polcy to trust a specific strong name:

  1. Right click on All_Code, and select New
  2. Create a new code group for your strong name, and hit next
  3. Select a strong name membership condition from the drop down box
  4. Hit the import button, and select your assembly.  The configuration tool will import your public key.  If you want to trust everything you sign with this key, leave the name and version boxes unchecked
  5. Select the FullTrust permission set

To modify the policy to allow full trust for all Intranet assemblies:

  1. Expand the All_Code code group
  2. Right click the LocalIntranet_Zone code group, and select properties
  3. Switch to the Permission Set tab, and select FullTrust

Updated 7/30/04: Fixed a typo