1

I have the following class:

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

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

Can someone provide an example in which inheriting from PrintData and/or invoking an overridden PrintString method will throw an exception?

Dabblernl
  • 15,831
  • 18
  • 96
  • 148

1 Answers1

1

Well, I have finally managed to have a program blow up as a direct cause of a failed inheritancedemand. You will need a VS solution with three projects. First the baseclass:

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);
            }
        }
    }
}

Then the derived classes in a different project:

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();
        }
    }   
}

and finally the main program in a third project:

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();      
        }
    }
}

To make the example work you have to reference the BaseClass assembly in the DerivedClasses assembly and both the BaseClass and DerivedClasses assemblies in the MethodSecuritySpike assembly. Moreover, make an appropriate test.ini file in any other location than the root of C:\ (otherwise windows security may play tricks with you)

Run the program (MethodSecuritySpike.exe). You will first see that an exception is caught while trying to read the ini file, thereafter the contents of the ini file are displayed nonetheless.

Next remove the comment slashes before the RegistryPermissionAttribute in the BaseClass namespace. Run the program: it refuses to run at all!

Explanation of the attributes:
In Baseclass:
[FileIOPermission(SecurityAction.Deny, AllFiles = FileIOPermissionAccess.Read)]
Will cause the exception when the PrintIniFile is invoked in the base class (simulates a situation in which Code Access Security tries to prevent accessing an ini file) The InheritanceDemandExceptionThrower class bypasses this security declaration by overriding the PrintIniFile method and calling the ProtectedPrint method directly.(Simulating a security breach)

[RegistryPermission(SecurityAction.InheritanceDemand,Unrestricted = true)]
Requieres that classes that inherit from IniPrinterBase have the above permission (arbitrarily chosen because it will need a high trust level) As the DerivedClasses.dll is explicitly denied this permission the program fails to run when this attribute is uncommented.

In DerivedClasses:
[assembly:RegistryPermission(SecurityAction.RequestRefuse,Unrestricted = true)]
Specifies that a request for RegistryAccess should be denied (simulates a partial trust environment). Normally this does not throw an exception as the classes in the DerivedClasses.dll do not access the registry. However, when the inheritancedemand is made active the DerivedClasses.dll needs the registrypermission to be able to instantiate its two classes and blows up.

Easy! ;-)

Dabblernl
  • 15,831
  • 18
  • 96
  • 148