C# 中的沙箱 IronPython 触发 SecurityException

5 投票
2 回答
1160 浏览
提问于 2025-04-17 12:00

好的,下面是我现在的情况

private static AppDomain CreateSandbox()
{
  var permissions = new PermissionSet(PermissionState.None);
  permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

  permissions.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read| FileIOPermissionAccess.PathDiscovery, AppDomain.CurrentDomain.BaseDirectory));
  var appinfo = new AppDomainSetup();
  appinfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

  return AppDomain.CreateDomain("Scripting sandbox", null, appinfo, permissions, fullTrustAssembly);
}

当我尝试加载一些有问题的Python代码时

try
{
    var src = engine.CreateScriptSourceFromString(s.Python, SourceCodeKind.Statements);
    src.Execute(ActionsScope);
}
catch (Exception e)
{
    ExceptionOperations eo = engine.GetService<ExceptionOperations>();
    string error = eo.FormatException(e);
    Debug.WriteLine(error);
}

这让我遇到了一个SecurityException,而不是让我看到代码中实际的错误信息。如果我设置PermissionSet(PermissionState.Unrestricted),那就没问题了。

有没有人知道我需要什么权限才能捕捉到这些烦人的错误呢?

System.Security.SecurityException was caught
  Message=Request failed.
  Source=Microsoft.Scripting
  GrantedSet=<PermissionSet class="System.Security.PermissionSet"
version="1">
<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Read="F:\Programming\OCTGN\octgnFX\Octgn\bin\ReleaseMode with Debug\"
PathDiscovery="F:\Programming\OCTGN\octgnFX\Octgn\bin\ReleaseMode with Debug\"/>
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="Execution"/>
</PermissionSet>

  PermissionState=<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>

  RefusedSet=""
  Url=file:///F:/Programming/OCTGN/octgnFX/Octgn/bin/ReleaseMode with Debug/Microsoft.Scripting.DLL
  StackTrace:
       at Microsoft.Scripting.SyntaxErrorException.GetObjectData(SerializationInfo info, StreamingContext context)
       at System.Runtime.Serialization.ObjectCloneHelper.GetObjectData(Object serObj, String& typeName, String& assemName, String[]& fieldNames, Object[]& fieldValues)
       at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)
       at Octgn.Scripting.Engine.LoadScripts() in F:\Programming\OCTGN\octgnFX\Octgn\Scripting\Engine.cs:line 58
  InnerException: 

2 个回答

1

你可以试试这个叫做 ObjectHandle ExecuteAndWrap(ScriptScope scope, out ObjectHandle exception) 的方法。简单来说,当你只是捕捉异常的时候,异常会从远程的地方传到你这边,然后在你调用 FormatException 的时候又会传回去。看起来这个异常是在传回你应用程序的过程中出现的。

如果你使用 ExecuteAndWrap 这个方法,你就能直接得到结果和可能的异常的引用,这样就避免了数据的转换过程。然后你可以把这个引用传给 ExceptionOperations.FormatException。

2

根据错误信息,你的代码里有语法错误,所以Python运行时抛出了一个SyntaxErrorException(语法错误异常)。这个异常没有被捕捉到,所以它必须在应用程序的不同部分之间进行传递。

我觉得现在的问题是SyntaxErrorExceptionGetObjectData()方法被标记为[SecurityCritical],这意味着只有完全信任的代码才能调用它。

撰写回答