Obecnie próbuję stworzyć bardzo prostą piaskownicę.
Niektóre klasy A mają metodę Wykonaj, która jest wywoływana w innym AppDomain
niż wywołujący.
Problem polega na tym, że mam tylko pozwolenie na wykonanie, a refleksja i tak jest możliwa.
Oto przykładowy kod:
[Serializable]
public class A : MarshalByRefObject
{
public void Execute()
{
typeof(A).GetConstructor(Type.EmptyTypes).Invoke(null); // Fine - Why?
typeof(B).GetConstructor(Type.EmptyTypes).Invoke(null); // Fine - Why?
}
}
public class B
{
}
class Program
{
static void Main(string[] args)
{
PermissionSet set = new PermissionSet(PermissionState.None);
SecurityPermission security = new SecurityPermission(SecurityPermissionFlag.Execution);
set.AddPermission(security);
Evidence evidence = new Evidence();
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = "C:";
AppDomain domain = AppDomain.CreateDomain
(
"hello",
evidence,
setup,
set
);
A a = (A)domain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(A).FullName);
a.Execute();
}
}
AKTUALIZACJA
Świetnie! W końcu to zrobiłem.
Dzięki waszym radom poprawiłem swój kod i chciałbym się nim z wami podzielić, ponieważ trudno mi było zrozumieć, jak nie używać CAS, ale używać tego samego rodzaju uprawnień w nowym .NET 4 Model bezpieczeństwa .x i nowszy oraz sposób piaskownicy przy użyciu AppDomain
. Otóż to:
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
namespace ConsoleApplication1
{
[Serializable]
public class A : MarshalByRefObject
{
public void Execute()
{
B b = new B();
// BOMB! ERROR! Security demand: reflection forbidden!
b.GetType()
.GetMethod("ExecuteInB", BindingFlags.Instance | BindingFlags.NonPublic)
.Invoke(b, null);
}
}
public class B
{
private void ExecuteInB()
{
}
}
class Program
{
static void Main(string[] args)
{
PermissionSet set = new PermissionSet(PermissionState.None);
SecurityPermission security = new SecurityPermission(PermissionState.None);
security.Flags = SecurityPermissionFlag.Execution;
set.AddPermission(security);
Evidence evidence = new Evidence();
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = "C:";
AppDomain domain = AppDomain.CreateDomain
(
"hola",
evidence,
setup,
set
);
A a = (A)domain.CreateInstanceAndUnwrap("ConsoleApplication1", "ConsoleApplication1.A");
a.Execute();
}
}
}
3 odpowiedzi
W przypadku wywołania niedostępnego członka wymagane jest zezwolenie na odbicie. A
i B
są typami publicznymi z publicznymi konstruktorami, a więc są dostępne. Możesz wywołać te konstruktory bez odbicia, więc nie ma żadnych wymagań, gdy próbujesz to zrobić z odbiciami.
Co więcej, używanie refleksji do odkrywania jest zawsze legalne; możesz przesłuchać obiekt i poprosić go o listę jego prywatnych członków, nawet bez zezwolenia na odbicie. Wymagane jest zezwolenie tylko wtedy, gdy próbujesz wywołać wywołanie członka prywatnego.
Z Biblioteki MSDN: ReflectionPermission
kontroluje dostęp do niepublicznych typów i członków za pośrednictwem interfejsów API System.Reflection. Bez ReflectionPermission
kod może używać odbicia, aby uzyskać dostęp tylko do publicznych członków obiektów.
Czy sprawdziłeś swój kod w .net 3.5? Platforma .NET 4 ma nowy model zabezpieczeń, w którym zestawy dotacji nie wpływają już na sansbox. Byłem tym poważnie ugryziony, gdy chciałem przetestować kod przeznaczony do uruchamiania w kontekstach o średnim zaufaniu w procesie pełnego zaufania .net.
Możliwym rozwiązaniem jest zmuszenie środowiska CLR do korzystania ze starszego modelu zabezpieczeń, a następnie jawne odrzucenie ReflectionPermission w nowej AppDomain.
Przepraszam za częściową odpowiedź. Korzystam teraz z komórki, ale sprawdzę jutro. Mam nadzieję, że dzięki temu zaczniesz.
Podobne pytania
Nowe pytania
c#
C # (wymawiane „patrz ostro”) jest językiem programowania wysokiego poziomu, statycznie typowanym, wieloparadygmatowym opracowanym przez firmę Microsoft. Kod C # zwykle jest przeznaczony dla rodziny narzędzi Microsoft .NET i czasów wykonywania, do których należą między innymi .NET Framework, .NET Core i Xamarin. Użyj tego tagu w przypadku pytań dotyczących kodu napisanego w C # lub C # formalnej specyfikacji.