限制插件汇编代码访问

Posted

技术标签:

【中文标题】限制插件汇编代码访问【英文标题】:Restrict plug-in assembly code access 【发布时间】:2009-10-05 13:35:16 【问题描述】:

我想创建一个插件架构,我可以在其中将程序集 API 限制为非常受限的东西,即只允许函数的白名单。 是否可以限制插件程序集可以调用的功能/方法? 我可以使用 AppDomains 吗?

谁有一个简单的例子?

【问题讨论】:

你指的是哪些函数/方法?您的或 .NET Framework 函数? 两者都可以,如果需要,我可以将 .NET 封装在我的中。 重新编辑 InternalsVisibleTo 属性 【参考方案1】:

.NET 添加了可能符合要求的“托管插件框架”。它具有以下特点:

隔离。如果需要,插件在自己的 AppDomain 中运行,如果您需要这种级别的隔离,甚至可以在自己的自己的进程中运行。 合同沟通。您设置合同,这是您分发给插件作者的唯一内容。他们不需要知道您的应用程序的任何其他方面。 发现。具有用于从装满程序集的文件夹中嗅出插件的内置机制。 安全。加载插件时会自动应用 CASPOL 集。有一些内置选项可以让这变得简单(请参阅AddInSecurityLevel Enum)。

大多数隔离方法也限制了通信和 UI 集成。 MAF 试图绕过这些限制。它要求您设置合同通信管道,但会执行您通常必须自己完成的大部分工作。

例如,将在两个独立进程中运行的 UI 片段拼接在一起(这很神奇),或者能够跨 AppDomain 或进程引发事件。这些事情并非微不足道,但 MAF 在这方面有很大帮助。

示例

这是一个简单的例子。作为“Shell”作者,您将向您的插件作者提供合同。这是一个典型的合约(它只是一个抽象类):

public abstract class Calculator 

    public abstract double Add(double a, double b);    
    public abstract double Subtract(double a, double b);
    public abstract double Multiply(double a, double b);
    public abstract double Divide(double a, double b);

如果插件作者想写一个插件,他们可以简单地继承这个合约并添加“Addin”属性:

[AddIn("Sample Calculator AddIn", Version="1.0.0.0")]
public class SampleCalculatorAddIn : Calculator

    public override double Add(double a, double b)
    
        return a + b;
    
    public override double Subtract(double a, double b)
    
        return a-b;
    
    public override double Multiply(double a, double b)
    
        return a * b;
    
    public override double Divide(double a, double b)
    
        return a / b;
    

以下是加载这些插件并与它们交互的方式:

// In this sample we expect the AddIns and components to 
// be installed in the current directory
String addInRoot = Environment.CurrentDirectory;

// Check to see if new AddIns have been installed
AddInStore.Rebuild(addInRoot);

// Look for Calculator AddIns in our root directory and 
// store the results
Collection<AddInToken> tokens = 
    AddInStore.FindAddIns(typeof(Calculator), addInRoot);

// Ask the user which AddIn they would like to use
AddInToken calcToken = ChooseCalculator(tokens);

// Activate the selected AddInToken in a new AppDomain set sandboxed 
// in the internet zone. You can find out what this gives access
// to by running "mscorcfg.msc", but essentially this will limit
// any access to the filesystem and other obvious OS services.
// Use of reflection is also very limited in this zone.
Calculator calculator = 
    calcToken.Activate<Calculator>(AddInSecurityLevel.Internet);

// Run the read-eval-print loop
RunCalculator(calculator);

这就是要点。显然不止这些,但你明白了。

进一步阅读

很好的介绍文章https://web-beta.archive.org/web/20140820145919/http://msdn.microsoft.com/en-us/magazine/cc163476.aspx

MSDN 上的概述http://msdn.microsoft.com/en-us/library/bb384200.aspx

Codeplex 上的 System.Addin(大量样本)http://www.codeplex.com/clraddins

工具

Pipeline Builder(帮助在 shell 和插件之间生成通信管道)http://clraddins.codeplex.com/wikipage?title=Pipeline%20Builder&referringTitle=Home

System.Addin 的 Fx-Cop 规则http://clraddins.codeplex.com/wikipage?title=Add-in%20FxCop%20Rules&referringTitle=Home

【讨论】:

【参考方案2】:

使用internal 关键字来处理您不希望其他程序集看到的任何内容都应该有效。我错过了什么吗?

你要做的是:

将所有“完全权限”项目设为内部 在 AssemblyInfo.cs 中,为您完全信任的每个程序集添加 InternalsVisibleTo 属性。代码示例:[InternalsVisibleTo("fullNameOfAssemblyFromOtherLibrariesAssemblyInfoFile")] Ta-da,你所有的代码都是安全的! (除了反射,无论如何你都不能真正停止)

【讨论】:

是的,我希望一些代码以完全权限运行,而其他代码以非常有限的权限集运行。使用 internal 会阻止所有程序集访问它,而不仅仅是插件程序。代码访问安全的方向是正确的,它回答了第一个/第二个问题,但没有回答第三个问题,即一个简单的例子。 我不明白。任何你想看到内部的东西,在你的原始程序集中设置 InternalsVisibleTo 属性。插件程序集没有这种能力,因此看不到任何需要“完全权限”的东西。我会用一些链接编辑我的答案。 您可以通过应用适当的 CASPOL 来限制反射的使用。【参考方案3】:

代码访问安全应该是可能的。

我找到了这篇文章。

http://www.15seconds.com/Issue/040121.htm

AppDomain 策略级别将是您的

编辑:提供示例代码非常复杂。不过 MSDN 应该会给你一些好的提示:http://msdn.microsoft.com/en-us/library/yctbsyf4(VS.71).aspx

【讨论】:

这可行,但在完全信任的情况下,无论如何都会授予所有权限。 但是您可以配置一个信任度较低的 AppDomain 并在那里加载您的插件。 编辑我的答案:添加到 MSDN 的链接

以上是关于限制插件汇编代码访问的主要内容,如果未能解决你的问题,请参考以下文章

限制插件访问

限制访问java-melody监控url

一个appdomain可以限制在一个目录吗?

WordPress的Jetpack插件更新

k8s安全框架-rbac授权--网络访问限制

限制用户访问 CouchDB 中的某些文档