有人可以提供(链接)有用的InheritanceDemand示例吗?

时间:2009-06-15 19:59:54

标签: c# .net security

我有以下课程:

[UIPermission(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)]
    public class PrintData
    {
        protected string Data = "secret value";

        public virtual void PrintString()
        {
            Console.WriteLine(Data);
        }
    }

有人可以提供一个示例,其中继承PrintData和/或调用重写的PrintString方法会抛出异常吗?

1 个答案:

答案 0 :(得分:1)

好吧,我终于设法让一个程序爆炸,这是导致继承请求失败的直接原因。 您需要一个包含三个项目的VS解决方案。 首先是基类:

using System;
using System.IO;
using System.Security;
using System.Security.Permissions;

namespace BaseClass
{
    public abstract class IniPrinterBase
    {
        [FileIOPermission(SecurityAction.Deny, AllFiles = FileIOPermissionAccess.Read)]
        //[RegistryPermission(SecurityAction.InheritanceDemand,Unrestricted = true)]
        public virtual void PrintIniFile()
        {
            ProtectedPrint();
        }

        protected void ProtectedPrint()
        {
            try
            {
                var lines = File.ReadAllLines(@"G:\test.ini");
                foreach (var line in lines)
                {
                    Console.WriteLine(line);
                }
            }
            catch (SecurityException e)
            {

                Console.WriteLine("PRINT OF INI FILE FAILED!");
                Console.WriteLine(e.Message);
            }
        }
    }
}

然后是不同项目中的派生类:

using System.Security.Permissions;
using BaseClass;

[assembly:RegistryPermission(SecurityAction.RequestRefuse,Unrestricted = true)]
namespace DerivedClasses
{
    public class FileIOPermissionExceptionThrower : IniPrinterBase
    {
        public override void PrintIniFile()
        {
            base.PrintIniFile();
        }
    }

    public class InheritanceDemandExceptionThrower : IniPrinterBase
    {
        public override void PrintIniFile()
        {
            ProtectedPrint();
        }
    }   
}

最后是第三个项目中的主程序:

using System;
using DerivedClasses;

namespace MethodSecuritySpike
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine("Printing ini file from security enforced method:");
            var printer1 = new FileIOPermissionExceptionThrower();
            printer1.PrintIniFile();
            Console.WriteLine();
            Console.WriteLine("Bypassing security:");
            var printer2 = new InheritanceDemandExceptionThrower();
            printer2.PrintIniFile();
            Console.ReadLine();      
        }
    }
}

要使示例工作,您必须引用DerivedClasses程序集中的BaseClass程序集以及MethodSecuritySpike程序集中的BaseClass和DerivedClasses程序集。 此外,在C:\的根目录之外的任何其他位置制作一个合适的test.ini文件(否则Windows安全可能会与你一起玩弄)

运行程序(MethodSecuritySpike.exe)。您将首先看到在尝试读取ini文件时捕获到异常,然后仍显示ini文件的内容。

接下来删除BaseClass命名空间中RegistryPermissionAttribute之前的注释斜杠。运行程序:它完全拒绝运行!

属性说明:
在基础班:
[FileIOPermission(SecurityAction.Deny,AllFiles = FileIOPermissionAccess.Read)]
在基类中调用PrintIniFile 时将导致异常(模拟代码访问安全性试图阻止访问ini文件的情况) InheritanceDemandExceptionThrower类通过重写PrintIniFile方法并直接调用ProtectedPrint方法来绕过此安全声明。(模拟安全漏洞)

[RegistryPermission(SecurityAction.InheritanceDemand,Unrestricted = true)]
要求从IniPrinterBase继承的类具有上述权限(任意选择因为它需要高信任级别) 由于DerivedClasses.dll被明确拒绝此权限,因此在取消注释此属性时程序无法运行。

在DerivedClasses中:
[assembly:RegistryPermission(SecurityAction.RequestRefuse,Unrestricted = true)]
指定应拒绝对RegistryAccess的请求(模拟部分信任环境)。通常,这不会引发异常,因为DerivedClasses.dll中的类不访问注册表。 但是,当inheritanceCmand.dll处于活动状态时,DerivedClasses.dll需要registrypermission才能实例化其两个类并且会爆炸。

轻松! ; - )