.NET Security- прозрачный код, уровень 2 и разрешения

Чтение документов / прототипов и, кажется, я не понимаю общую картину безопасности. Хорошо, я понимаю и даже создал прототип трехуровневой модели безопасности (прозрачный код, код, критичный для безопасности, и код, критичный для безопасности). Работает отлично.

Я не могу понять, как это связано с разрешениями. Например, мне нужен код SecurityTransparent, который не имеет каких-либо разрешений, кроме выполнения, а затем мне нужен код SecurityCritical, который имеет все разрешения. Я пытался играть в ConsoleApp. В ConsoleApp в домене по умолчанию код SecurityTransparent имеет все разрешения и может фактически делать все, что захочет, например, создавать файлы, записывать ключи reg и т. Д. Затем, если я создаю "песочницу", известную как AppDomain, и ограничиваю разрешения, весь код, выполняющий домен, имеет такие разрешения. Например, ни Security Transparent, ни Security Critical не имеют доступа, например, к файлам, реестру и т. Д. Итак, я явно не понимаю, что дает эта трехуровневая модель безопасности (прозрачный код, код, безопасный для безопасности, и код, критичный для безопасности) нам, если критичный для безопасности код при запуске в песочнице имеет тот же уровень разрешений, что и прозрачный для безопасности.

Другой вопрос заключается в том, что означает "свойство полного доверия" и когда это может быть что-то иное, чем полное доверие, и как все это влияет на безопасность.

Обновление 1 - Код

class Program
{
    public static PermissionSet GetPermissionSet()
    {
        var permissions = new PermissionSet(PermissionState.None);
        permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

        // Just to be able to write to the Console
        permissions.AddPermission(new FileIOPermission(PermissionState.Unrestricted));

        return permissions;
    }

    public static string GetDomainInfo(AppDomain domain)
    {
        StringBuilder sb = new StringBuilder();
        //check the domain trust
        sb.AppendFormat("Domain Is Full Trusted: {0} \n", domain.IsFullyTrusted);
        //show the number of the permission granted to the assembly
        sb.AppendFormat("\nPermissions Count: {0} \n\n\n", domain.PermissionSet.Count);
        sb.AppendFormat("\nPermissions Is Homogenous: {0} \n\n\n", domain.IsHomogenous);
        return sb.ToString();
    }

    public static StrongName GetTypeAssemblyStringName(Type type)
    {
        var name = type.Assembly.GetName();
        return new StrongName(new StrongNamePublicKeyBlob(name.GetPublicKey()), name.Name, name.Version);
    }

    public static AppDomain CreateDomain()
    {
        //create  the AppDomainSetup
        AppDomainSetup info = new AppDomainSetup();

        //set the path to the assembly to load.
        info.ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

        //create the domain
        AppDomain domain = AppDomain.CreateDomain(
            "MyCoolDomain", 
            null, 
            info, 
            GetPermissionSet(),
            GetTypeAssemblyStringName(typeof(SecurityCriticalApi1Class)), /* Get's full trust but operates as partial trust */
            GetTypeAssemblyStringName(typeof(SecurityCriticalApi2Class)), /*                       same                     */
            GetTypeAssemblyStringName(typeof(SecuritySafeApiClass))       /*                       same                     */
            );

        return domain;

    }

    public static void ShowAssemblyInfo(Type type)
    {
        var a = Assembly.GetAssembly(type);
        ShowAssemblyInfo(a);
    }

    public static void ShowAssemblyInfo(Assembly a)
    {
        var sb = new StringBuilder();

        //show the transparency level
        sb.AppendFormat("\nAssembly: {0}\n", a.GetName().Name);
        sb.AppendFormat("Security Rule Set: {0}\n", a.SecurityRuleSet);

        //show if it is full trusted
        sb.AppendFormat("Is Fully Trusted: {0}\n", a.IsFullyTrusted);

        try
        {
            sb.AppendFormat("Permissions Count: {0} \n", a.PermissionSet.Count);
        }
        catch (Exception ex)
        {
            sb.AppendFormat("Error while trying to get the Permission Count: {0} \n", ex.Message);
        }

        Console.WriteLine(sb);
    }

    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Started");

            var domain = CreateDomain();

            Console.WriteLine(GetDomainInfo(domain));

            Type t = typeof(TransparentApiClass);
            ObjectHandle handle = Activator.CreateInstanceFrom(domain, t.Assembly.ManifestModule.FullyQualifiedName, t.FullName);
            var api = (TransparentApiClass)handle.Unwrap();
            api.DoIt();

            Console.WriteLine("Stopped");
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
}

[SecuritySafeCritical]
public class SecuritySafeApiClass
{
    public void DoIt()
    {
        Console.WriteLine("SecuritySafeApiClass calling SecurityCritical API");

        var api = new SecurityCriticalApi1Class();
        api.DoIt();

        Console.WriteLine("SecuritySafeApiClass Done");
    }
}


public class SecurityCriticalApi1Class
{
    public void DoIt()
    {
        Console.WriteLine("SecurityCriticalApi1Class");

        // Throws exception - require permission
        var key = Registry.ClassesRoot.GetSubKeyNames();

        Console.WriteLine("SecurityCriticalApi1Class Done");
    }
}

Если я все понимаю правильно, моё описание проблемы может быть сокращено - в моем случае код, загруженный с помощью Full Trust путем указания соответствующих строгих имен в настройке домена, действует как частичное доверие, означает, что означает, что разрешения работают с теми же разрешениями, что и у doman.

Обновление 2 Я пытался использовать открытый класс Assert SecuritySafeApiClass { public void Assert() { var permissions = new PermissionSet(PermissionState.Unrestricted); permissions.AddPermission(новый RegistryPermission(PermissionState.Unrestricted)); permissions.Assert(); }

    public void DoIt()
    {
        Console.WriteLine("SecuritySafeApiClass calling SecurityCritical API");

        Assert();

        var api = new SecurityCriticalApi1Class();
        api.DoIt();

        Console.WriteLine("SecuritySafeApiClass Done");
    }
}

И это не помогло ((Ошибка, которую я получаю, это:

Failed to execute action. error System.Security.SecurityException: Request for t
he permission of type 'System.Security.Permissions.RegistryPermission, mscorlib,
 Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
   at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMa
rk& stackMark, Boolean isPermSet)
   at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, S
tackCrawlMark& stackMark)
   at System.Security.CodeAccessPermission.Demand()
   at Microsoft.Win32.RegistryKey.CheckPermission(RegistryInternalCheck check, S
tring item, Boolean subKeyWritable, RegistryKeyPermissionCheck subKeyCheck)
   at Microsoft.Win32.RegistryKey.GetSubKeyNames()
   at SecurityCriticalApi1.SecurityCriticalApi1Class.DoIt() in C:\Dev\SecurityPr
oofOfConcept\SecurityCriticalApi1\SecurityCriticalApi1Class.cs:line 20
   at SecuritySafeApi.SecuritySafeApiClass.DoIt() in C:\Dev\SecurityProofOfConce
pt\SecuritySafeApi\SecuritySafeApiClass.cs:line 29
   at TransparentApi.TransparentApiClass.<DoIt>b__2_0()
   at TransparentApi.TransparentApiClass.TryToExecute(Action a, String caller)
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.RegistryPermission
The Zone of the assembly that failed was:
MyComputer

0 ответов

Другие вопросы по тегам