C# 中的断言权限

发布于 2025-01-02 14:01:50 字数 1211 浏览 0 评论 0原文

我正忙于理解 C# 中的安全性内容,并且正在努力了解 Assert 的工作原理。我正在使用.net 3.5。

我制作了一个示例应用程序来尝试解决这个问题。

调用方法:

[FileIOPermission(SecurityAction.Deny, ViewAndModify = @"C:\")]
    static void Main(string[] args)
    {
        WriteTest testWriter = new WriteTest();
        testWriter.Test();
        Console.Read();
    }

在一个单独的类库中,我有:

public class WriteTest
{
    public void Test()
    {
        try
        {
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, @"C:\");
            permission.Assert();
            using (StreamWriter sw = new StreamWriter(@"C:\test.txt"))
            {
                sw.WriteLine("testing!");
                sw.Flush();
            }
            Console.WriteLine("Writen to file!");
        }
        catch (SecurityException sec)
        {
            Console.WriteLine("No privileges!");
        }
    }
}

此代码执行得很好。它将写入文件。我的问题是这到底是如何运作的?如果我可以断言我想要的权限以便它跳过检查,这不会使安全类失效吗?如果我将断言更改为需求,它会引发异常。

安全类的目的是不允许我设置权限,以便当我调用第三方类时我可以防止它变得流氓并做我不希望它做的事情吗?我知道如果我在 AppDomain 中加载 dll,即使第三方 DLL 确实使用了 Assert,我也会得到这种效果,但如果我直接调用它就会起作用,这似乎很奇怪。我尝试阅读有关 Assert 的 MSDN 文档,但发现它很难理解。

I'm busy trying to understand the security stuff in c# and I'm struggling to see how Assert works. I'm using .net 3.5.

I made a sample app to try figure this out.

Calling method:

[FileIOPermission(SecurityAction.Deny, ViewAndModify = @"C:\")]
    static void Main(string[] args)
    {
        WriteTest testWriter = new WriteTest();
        testWriter.Test();
        Console.Read();
    }

In a seperate class library I have:

public class WriteTest
{
    public void Test()
    {
        try
        {
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, @"C:\");
            permission.Assert();
            using (StreamWriter sw = new StreamWriter(@"C:\test.txt"))
            {
                sw.WriteLine("testing!");
                sw.Flush();
            }
            Console.WriteLine("Writen to file!");
        }
        catch (SecurityException sec)
        {
            Console.WriteLine("No privileges!");
        }
    }
}

This code executes fine and all. It will write to the file. My question is how exactly does this work? Does this not invalidate the security classes if I can just Assert the permissions I want so that it skips the checks? If I change Assert to Demand it throws an exception.

Is the point of the security classes not to allow me to set permissions so that when I call a third party class I can prevent it from going rogue and doing stuff I don't want it to do? I know if I load the dll in an AppDomain I will get this effect even if the third party DLL does use Assert, it just seems strange that if I call it directly it will work. I've tried reading the MSDN documentation on Assert but I'm finding it hard to understand.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吻风 2025-01-09 14:01:50

较少特权代码(“程序集A”)调用更多特权代码(“程序集B”)来执行时,Assert()很有用一些任务。为了执行该任务,程序集 B 需要运行需要强大权限的代码,而程序集 A 可能没有该权限。因此,程序集 B 首先请求一个不太强大的权限(首先执行该任务的权限),然后断言更强大的权限来实际执行该任务。

例如,假设部分信任的 Silverlight 应用程序想要使用 System.Net.WebRequest 类发出 HTTP 请求。建立网络连接需要 SocketPermission,但这是一个强大的低级权限,不应授予来自 Internet 的不受信任的代码。因此,WebRequest 需要一个较弱的权限 WebPermission,然后在继续建立网络连接之前断言 SocketPermission

现在,在您的特定示例中,Assert() 会覆盖 Deny,因为类库与应用程序以相同的权限级别运行 —应用程序和类库都可能以完全信任的方式运行。程序集始终可以 Assert() 其授予集中的任何权限。要对类库强制执行Deny,您必须将类库放入沙箱中。

注意:在 .NET 4.0 中,Deny 已被弃用。来自 MSDN 库<​​/a>:

已删除对执行 Deny、RequestMinimum、RequestOptional 和 RequestRefuse 权限请求的运行时支持。一般来说,这些请求没有得到很好的理解,并且在使用不当时可能会出现安全漏洞:

  • 拒绝操作很容易被断言操作覆盖。如果权限位于程序集的授予集中,则程序集中的代码能够执行该权限的断言操作。断言阻止了在堆栈上看到拒绝,从而使其无效。

Assert() is useful when less-privileged code ("Assembly A") calls more-privileged code ("Assembly B") to perform some task. To carry out that task, Assembly B needs to run code that requires a powerful permission—a permission that Assembly A might not have. So Assembly B first demands a less-powerful permission (the permission to perform the task in the first place) and then asserts the more-powerful permission to actually carry out the task.

For example, suppose a partial-trust Silverlight app wants to make an HTTP request using the System.Net.WebRequest class. Establishing a network connection requires SocketPermission, but this is a powerful, low-level permission that shouldn't be granted to untrusted code from the Internet. So WebRequest demands a less-powerful permission, WebPermission, and then asserts SocketPermission before going on to establish the network connection.

Now, in your particular example, the Assert() overrides the Deny because the class library is running at the same privilege level as the application—both the application and class library are likely running as Full Trust. An assembly can always Assert() any permission in its grant set. To enforce the Deny on the class library, you would have to put the class library in a sandbox.

Note: In .NET 4.0, Deny has been deprecated. From MSDN Library:

Runtime support has been removed for enforcing the Deny, RequestMinimum, RequestOptional, and RequestRefuse permission requests. In general, these requests were not well understood and presented the potential for security vulnerabilities when they were not used properly:

  • A Deny action could be easily overridden by an Assert action. The code in an assembly was able to execute an Assert action for a permission if the permission was in the grant set for the assembly. The Assert prevented the Deny from being seen on the stack, making it ineffective.
心作怪 2025-01-09 14:01:50

Assert() 方法会导致代码访问安全 (CAS) 停止在特定权限检查请求上遍历堆栈。

Assert是一个可以在代码访问权限上调用的方法
类和 PermissionSet 类。您可以使用断言来启用
您的代码(和下游调用者)执行您的代码所执行的操作
有权限执行,但其调用者可能无权执行。
安全断言改变了运行时的正常过程
在安全检查期间执行。当您声明权限时,它
告诉安全系统不要检查代码的调用者
所声称的许可。

使用断言方法

我想你想要Demand()< /code>

感兴趣:

The Assert() method causes Code Access Security (CAS) stop walking the stack on a specific permission check request.

Assert is a method that can be called on code access permission
classes and on the PermissionSet class. You can use Assert to enable
your code (and downstream callers) to perform actions that your code
has permission to do but its callers might not have permission to do.
A security assertion changes the normal process that the runtime
performs during a security check. When you assert a permission, it
tells the security system not to check the callers of your code for
the asserted permission.

Using the Assert Method

I think you want Demand()

Of Interest:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文