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, GetObjectData
has 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:
SecurityCritical
, so where's the problem?SecurityCriticalAttribute
is ignored in my sandbox, how will this class behave in other partial trust hosts, such as IIS/ASP.NET or SQL Server?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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With