- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个插件系统来在我的服务器应用程序(C#、.NET 4.0)中运行客户端提供的不受信任的代码。为此,我在一个新的沙盒 AppDomain 中运行每个插件。
但是,我陷入了一个我并不真正理解其原因的安全异常。我做了一个精简的控制台应用程序示例来说明问题:
namespace SandboxTest
{
class Program
{
static void Main( string[] args )
{
Sandbox sandbox = new Sandbox();
Console.ReadLine();
}
}
class Sandbox
{
AppDomain domain;
public Sandbox()
{
PermissionSet ps = new PermissionSet( PermissionState.None );
ps.AddPermission( new SecurityPermission( SecurityPermissionFlag.Execution ) );
try
{
domain = AppDomain.CreateDomain( "Sandbox", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation, ps );
domain.AssemblyLoad += new AssemblyLoadEventHandler( domain_AssemblyLoad );
domain.AssemblyResolve += new ResolveEventHandler( domain_AssemblyResolve );
}
catch( Exception e )
{
Trace.WriteLine( e.ToString() );
throw e;
}
}
static Assembly domain_AssemblyResolve( object sender, ResolveEventArgs args )
{
return null;
}
static void domain_AssemblyLoad( object sender, AssemblyLoadEventArgs args )
{
}
}
}
运行此代码后,我在 domain.AssemblyLoad 行上收到以下异常:
A first chance exception of type 'System.Security.SecurityException' occurred in SandboxTest.exe
'SandboxTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(RuntimeAssembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Object assemblyOrString, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
at System.Security.CodeAccessSecurityEngine.CheckHelper(PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, Object assemblyOrString, SecurityAction action, Boolean throwException)
at System.Security.CodeAccessSecurityEngine.CheckHelper(CompressedStack cs, PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, RuntimeAssembly asm, SecurityAction action)
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
at System.Security.CodeAccessPermission.Demand()
at System.DelegateSerializationHolder.GetDelegateSerializationInfo(SerializationInfo info, Type delegateType, Object target, MethodInfo method, Int32 targetIndex)
at System.MulticastDelegate.GetObjectData(SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectCloneHelper.GetObjectData(Object serObj, String& typeName, String& assemName, String[]& fieldNames, Object[]& fieldValues)
at System.AppDomain.add_AssemblyLoad(AssemblyLoadEventHandler value)
at SandboxTest.Sandbox..ctor() in C:\Dev\Projects\Botfield\SandboxTest\Program.cs:line 36
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.ReflectionPermission
The first permission that failed was:
<IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="MemberAccess"/>
The demand was for:
<IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="MemberAccess"/>
The granted set of the failing assembly was:
<PermissionSet class="System.Security.PermissionSet"
version="1">
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="Execution"/>
</PermissionSet>
我最好的猜测是,在没有所需安全权限的情况下,在新的沙盒 AppDomain 中执行了一些事件订阅代码,但我不知道如何在不为沙盒 AppDomain 提供完整反射能力的情况下解决它.请问有人有什么建议或解释吗?
最佳答案
简答:
用于将处理程序添加到事件 AppDomain.AssemblyLoad 的隐藏方法 - 由 SecurityCriticalAttribute 标记。检查 ILASM:
.method public hidebysig newslot specialname virtual final
instance void add_AssemblyLoad(class System.AssemblyLoadEventHandler 'value') cil managed
{
.custom instance void System.Security.SecurityCriticalAttribute::.ctor() = ( 01 00 00 00 )
// Code size 0 (0x0)
} // end of method AppDomain::add_AssemblyLoad
为了执行此方法,您必须在(您的沙箱域的)FullTrust 模式下执行它。故事结束。
长答案:
您正在处理跨域通信。意味着您的事件处理程序将在沙盒域的空间中执行,然后使用远程处理注册到您的父域。您提供的代码需要反射权限,无论您在该方法中使用什么事件都无关紧要 - 安全关键与否。
因此,如果您希望您的沙盒域与您的父域进行安全通信,您应该使用经典的 .NET 远程处理方法,此代码将不需要任何额外的权限,并允许将沙盒域上发生的事件通知父域:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Security.Permissions;
using System.Diagnostics;
using System.Reflection;
namespace SandboxTest
{
class Program
{
static void Main(string[] args)
{
Sandbox sandbox = new Sandbox();
Console.ReadLine();
}
}
class Sandbox
{
AppDomain domain;
public Sandbox()
{
PermissionSet ps = new PermissionSet(PermissionState.None);
ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
try
{
domain = AppDomain.CreateDomain("Sandbox", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation, ps);
var tp = typeof(MyInit);
var obj = (MyInit)domain.CreateInstanceAndUnwrap(tp.Assembly.FullName, tp.FullName);
var myCallBack = new MyCallBack();
myCallBack.Generated += new EventHandler(myCallBack_Generated);
obj.Subscribe(myCallBack);
obj.GenerateCallBackEvent();
}
catch (Exception e)
{
Trace.WriteLine(e.ToString());
throw e;
}
}
void myCallBack_Generated(object sender, EventArgs e)
{
//Executed in parent domain
}
}
public class MyCallBack:MarshalByRefObject
{
public void GenerateEvent()
{
//Executed in parent domain, but triggered by sandbox domain
if (Generated != null) Generated(this, null);
}
//for parent domain only
public event EventHandler Generated;
}
public class MyInit:MarshalByRefObject
{
public MyInit()
{
}
MyCallBack callback;
public void Subscribe(MyCallBack callback)
{
//executed on sandbox domain
this.callback = callback;
}
public void GenerateCallBackEvent()
{
//executed on sandbox domain
callback.GenerateEvent();
}
}
}
关于订阅域事件时的 C# AppDomain 沙箱安全异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7784615/
我正在学习 Spring 安全性,但我对它的灵活性感到困惑.. 我知道我可以通过在标签中定义规则来保护网址 然后我看到有一个@secure 注释可以保护方法。 然后还有其他注释来保护域(或 POJO)
假设有一个 key 加密 key 位于内存中并且未写入文件或数据库... byte[] kek = new byte[32]; secureRandom.nextBytes(kek); byte[]
我有 Spring Security 3.2.0 RC1 的问题 我正在使用标签来连接我 这表示“方法‘setF
我正在创建一个使用 Node Js 服务器 API 的 Flutter 应用程序。对于授权,我决定将 JWT 与私钥/公钥一起使用。服务器和移动客户端之间的通信使用 HTTPS。 Flutter 应用
在过去的几年里,我一直在使用范围从 Raphael.js 的 javascript 库。至 D3 ,我已经为自己的教育操纵了来自网络各地的动画。我已经从各种 git 存储库下载了 js 脚本,例如 s
在 python 中实现身份验证的好方法是什么?已经存在的东西也很好。我需要它通过不受信任的网络连接进行身份验证。它不需要太高级,只要足以安全地获取通用密码即可。我查看了 ssl 模块。但那个模块让我
我正在尝试学习“如何在 Hadoop 中实现 Kerberos?”我已经看过这个文档 https://issues.apache.org/jira/browse/HADOOP-4487我还了解了基本的
我有一个带有 apache2、php、mysql 的生产服务器。我现在只有一个站点 (mysite.com) 作为虚拟主机。我想把 phpmyadmin、webalizer 和 webmin 放在那里
前些天在网上看到防火墙软件OPNsense,对其有了兴趣,以前写过一个其前面的一个软件M0n0wall( 关于m0n0wa
我在 Spring Boot 和 oauth2(由 Google 提供)上编写了 rest 后端,在 "/login" 上自动重定向。除了 web 的 oauth 之外,我还想在移动后端进行 Fire
我想调用类 Foo,它的构造函数中有抽象类 Base。我希望能够从派生自 Base 的 Derived 调用 Foo 并使用 Derived覆盖方法而不是 Base 的方法。 我只能按照指示使用原始指
如何提高 session 的安全性? $this->session->userdata('userid') 我一直在为我的 ajax 调用扔掉这个小坏蛋。有些情况我没有。然后我想,使用 DOM 中的
我目前正在为某些人提供程序集编译服务。他们可以在在线编辑器中输入汇编代码并进行编译。然后编译它时,代码通过ajax请求发送到我的服务器,编译并返回程序的输出。 但是,我想知道我可以做些什么来防止对服务
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
目前,我通过将 session 中的 key 与 MySQl 数据库中的相同 key 相匹配来验证用户 session 。我使用随机数重新生成 session ,该随机数在每个页面加载时都受 MD5
Microsoft 模式与实践团队提供了一个很棒的 pdf,称为:“构建安全的 asp.net 应用程序”。 microsoft pdf 由于它是为 .Net 1.0 编写的,所以现在有点旧了。有谁知
在 Lua 中,通常会使用 math.random 生成随机值和/或字符串。 & math.randomseed , 其中 os.time用于 math.randomseed . 然而,这种方法有一个
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我们有一个严重依赖 Ajax 的应用程序。确保对服务器端脚本的请求不是通过独立程序而是通过坐在浏览器上的实际用户的好方法是什么 最佳答案 真的没有。 通过浏览器发送的任何请求都可以由独立程序伪造。 归
我正在寻找使用 WebSockets 与我们的服务器通信来实现 web (angular) 和 iPhone 应用程序。在过去使用 HTTP 请求时,我们使用请求数据、url、时间戳等的哈希值来验证和
我是一名优秀的程序员,十分优秀!