.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