none
<codeBase> vs. <probing> as it relates to the CAS FileIOPermission requirement RRS feed

  • Question

  • MSDN states that there are two ways to specify an assembly’s location in a .config file: either through the <codeBase> element or through the <probing> (path) element. Is seems, however that while the probing path approach requires no file IO permissions (CAS) whatsoever, the codebase approach demands Read and PathDiscovery access rights on the assembly’s location, even if it is located under the application’s base directory.

    Unfortunately we cannot grant any file IO access to the code in question, since it is presumed to be untrusted. Probing path significantly degrades performance when in becomes large (and it does in our case), and also at times we need to load multiple versions of the same assembly which is not supported by probing path approach. Hooking up the AssemblyResolve event carries both performance penalties and inability to load an assembly domain neutral.

    Given that I found no mentioning of the file IO permission requirement in codebase case anywhere on the net, I wanted to ask someone to first of all confirm the limitation, then possibly shed some light on its purpose and hopefully propose a work around.

    Below I included a sample code to reproduce the issue. If you run the resulting .exe with no arguments it will load itself successfully into a second restricted AppDomain using probing. If you run it with an argument of "1" (as in C:\...> CodeBaseTest.exe 1), it will try the same thing using codebase and fail. Finally running it with the argument of "2" (as in C:\...> CodeBaseTest.exe 2) will also succeed since it will grant the exact permissions demanded by the fusion to the restricted AppDomain – something we cannot allow in the real case.

    Thank you very much in advance for your answers.
     - Levi

    using System;
    using System.Security;
    using System.Security.Permissions;
    using System.Text;
    
    namespace CodeBaseTest
    {
        internal class Program
        {
            private const string ConfigXml = 
                "<configuration>" +
                "  <runtime>" +
                "    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">" +
                "      <dependentAssembly>" +
                "        <assemblyIdentity name=\"CodeBaseTest\"" +
                "          culture=\"neutral\" publicKeyToken=\"83ce6c492dbfae21\"/>" +
                "        <codeBase version=\"1.0.0.0\" href=\"CodeBaseTest.exe\"/>" +
                "      </dependentAssembly>" +
                "    </assemblyBinding>" +
                "  </runtime>" +
                "</configuration>";
    
            private static void Main(string[] args)
            {
    
                var scenario = "none";
                if (args.Length > 1 || 
                    (args.Length == 1 && args[0] != "1" && args[0] != "2"))
                {
                    Console.WriteLine("Usage: CodeBaseTest 1|2 ");
                    return;
                }
    
                if (args.Length == 1)
                {
                    scenario = args[0];
                }
                var setup = new AppDomainSetup 
                    {ApplicationBase = AppDomain.CurrentDomain.BaseDirectory};
    
                var perms = new PermissionSet(PermissionState.None);
    
                perms.AddPermission(
                    new ReflectionPermission(
                        ReflectionPermissionFlag.MemberAccess));
                perms.AddPermission(
                    new SecurityPermission(
                        SecurityPermissionFlag.Execution));
    
                switch (scenario)
                {
                    case "1":
                        {
                            setup.DisallowApplicationBaseProbing = true;
                            setup.SetConfigurationBytes(
                                Encoding.UTF8.GetBytes(ConfigXml));
                        }
                        break;
                    case "2":
                        {
                            setup.DisallowApplicationBaseProbing = true;
                            setup.SetConfigurationBytes(
                                Encoding.UTF8.GetBytes(ConfigXml));
                            perms.AddPermission(
                                new FileIOPermission(
                                    FileIOPermissionAccess.PathDiscovery |
                                    FileIOPermissionAccess.Read,
                                    setup.ApplicationBase + "\\CodeBaseTest.exe"));
                        }
                        break;
                }
    
                Console.WriteLine("Permissions granted are: \n{0}",  perms);
                var test = AppDomain.CreateDomain(
                    "TEST", AppDomain.CurrentDomain.Evidence, setup, perms);
                test.DoCallBack(DoWork);
            }
    
            private static void DoWork()
            {
                Console.WriteLine("Success");
            }
        }
    }
    

    Thursday, May 31, 2012 7:46 PM

All replies