6

I have an assembly marked with the AllowPartiallyTrustedCallersAttribute which contains a custom exception class. I want to make it serializable by overriding GetObjectData.

With .NET 4, GetObjectDatahas become a SecurityCritical method. This means that overrides also need to be SecurityCritical. Since my assembly is marked with the AllowPartiallyTrustedCallersAttribute, all code within is automatically SecurityTransparent unless specified otherwise. Therefore, I apply the SecurityCriticalAttribute to the GetObjectData override:

using System;
using System.Runtime.Serialization;
using System.Security;

[assembly:AllowPartiallyTrustedCallers]

namespace Library
{
  [Serializable]
  public class MyException : Exception
  {
    public string String;

    public MyException ()
    {
    }

    protected MyException (SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
      String = info.GetString ("String");
    }

    [SecurityCritical]
    public override void GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
    {
      info.AddValue ("String", String);
      base.GetObjectData (info, context);
    }
  }
}

This works fine in full trust scenarios, e.g., when I run code linking this assembly from my desktop.

However, when I use this class from a security sandbox (see below), I'm getting a TypeLoadException:

Inheritance security rules violated while overriding member: 'Library.MyException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.

My questions:

  • Why am I getting this exception? I did mark the override to be SecurityCritical, so where's the problem?
  • Since the SecurityCriticalAttribute is ignored in my sandbox, how will this class behave in other partial trust hosts, such as IIS/ASP.NET or SQL Server?
  • How do I implement a serializable exception class in .NET 4?

Sandboxing Code:

var evidence = new Evidence();
evidence.AddHostEvidence (new Zone (SecurityZone.Internet));
var setupInfo = AppDomain.CurrentDomain.SetupInformation;
var permissionSet = SecurityManager.GetStandardSandbox (evidence);
permissionSet.AddPermission (new ReflectionPermission (ReflectionPermissionFlag.MemberAccess));
permissionSet.AddPermission (new SecurityPermission (SecurityPermissionFlag.ControlEvidence));
var sandbox = AppDomain.CreateDomain ("Sandbox", evidence, setupInfo, permissionSet);
Fabian Schmied
  • 3,885
  • 3
  • 30
  • 49

3 Answers3

2

You've already answered the first part of your question yourself. Your assembly is being loaded as security transparent because it is not being loaded with full trust, so the SecurityCritical attribute is ignored. And so you get the exception.

Instead of overriding GetObjectData, you should handle the SerializeObjectState event and create a type that implements ISafeSerializationData to store the exception state for serialization. These exist for this exact scenario.

Carl Reinke
  • 345
  • 2
  • 12
1

You can't call code marked with the securitycriticalattribute from anything but fully trusted code:

The SecurityCriticalAttribute is equivalent to a link demand for full trust. A type or member marked with the SecurityCriticalAttribute can be called only by fully trusted code; it does not have to demand specific permissions. It cannot be called by partially trusted code.

There's a related question here discussing the use of securitysafecriticalattribute.

Community
  • 1
  • 1
vinny
  • 1,810
  • 15
  • 21
  • 1
    Actually, I don't call the SecurityCritical member (`GetObjectData`), I just want to override it without violating the "inheritance security rules". Is this not possible from within a partially trusted assembly? – Fabian Schmied Jan 03 '13 at 08:30
  • I don't think so as your override is still marked with the attribute. It looks like the securitysafecritical attribute will get you what you want, though. It'll mark your override as security critical and safely accessible by transparent code. From the link above: "Types or members that are marked with the SecuritySafeCriticalAttribute attribute can be accessed by partially trusted types and members." – vinny Jan 03 '13 at 14:03
  • No, `SecuritySafeCrititcal` cannot be used to override a `SecurityCritical` method. (I tried; with `SecuritySafeCritical` I'm getting the "inheritance security rules" exception even with full trust.) – Fabian Schmied Jan 04 '13 at 07:55
1

Well, I know this post is rather aged, but from my observation recently, if you do not give an assembly FullTrust in the sandboxed AppDomain, all the code in the loaded assembly will be SeurityTransparent. This means the SecurityCriticalAttribute applied to MyException.GetObjectData will just do nothing. It will be SeurityTransparent, and will surely not compatible with its base method, which is SecurityCritical.

Hope this tip will be of some help.

See https://learn.microsoft.com/en-us/dotnet/framework/misc/how-to-run-partially-trusted-code-in-a-sandbox for how to mark certain assemblies in the sandboxed AppDomain as FullyTrusted.

CXuesong
  • 552
  • 5
  • 12