What I need to do is : Read a local C#
text file, execute a method from that. This is what I'm doing.
- Read all text from the file
- Compile into a local
x.dll
withCSharpCodeProvider
- Load the dll with
Assembly.LoadFrom()
- Then execute the method with
GetType().GetMethod().Invoke()
It works fine. Now, I want to run this code securely, i.e. restrict this code from accessing the file system, network etc. Basically, I need to run this with minimal privileges.
I tried the code from Restrict plugin access to file system and network via appdomain (answer by @Babar), but still not working as expected. The code in the text file is still able to access file system.
What I'm missing here? Any other way to make it work?
The code (for loading and executing the assembly)
public class Sandboxer
{
public static T GetResult<T>(string untrustedAssemblyDirectory, string assemblyFullPath, string className, string methodName, object[] methodParameters)
{
AppDomainSetup adSetup = new AppDomainSetup();
adSetup.ApplicationBase = Path.GetFullPath(untrustedAssemblyDirectory);
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>();
AppDomain newDomain = AppDomain.CreateDomain("Sandboxer", null, adSetup, permSet, fullTrustAssembly);
ObjectHandle handle = Activator.CreateInstanceFrom(
newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,
typeof(Sandboxer).FullName
);
Sandboxer newDomainInstance = (Sandboxer)handle.Unwrap();
return newDomainInstance.ExecuteUntrustedCode<T>(assemblyFullPath, className, methodName, methodParameters);
}
public T ExecuteUntrustedCode<T>(string assemblyName, string typeName, string entryPoint, Object[] parameters)
{
var method = Assembly.LoadFrom(assemblyName).GetType(typeName).GetMethod(entryPoint);
try
{
T retVal = (T)method.Invoke(null, parameters);
return retVal;
}
catch (Exception ex)
{
var expMsg = string.Empty;
(new PermissionSet(PermissionState.Unrestricted)).Assert();
expMsg = "Exception :\n{0}" + ex.ToString();
CodeAccessPermission.RevertAssert();
throw new ApplicationException(expMsg);
}
}
}