views:

388

answers:

2

Hi,

I have an [AllowPartiallyTrustedCallers] class library containing subtypes of the System.DataAnnotations.ValidationAttribute. The library is used on contract types of WCF services.

In .NET 2/3.5, this worked fine. Since .NET 4.0 however, running a client of the service in the Visual Studio debugger results in the exception "Inheritance security rules violated by type: '(my subtype of ValidationAttribute)'. Derived types must either match the security accessibility of the base type or be less accessible." (System.TypeLoadException)

The error appears to occure only when all of the following conditions are met:

  1. a subclass of ValidationAttribute is in an AllowPartiallyTrustedCallers assembly
  2. reflection is used to check for the attribute
  3. the Visual Studio hosting process is enabled (checkbox on Project properties, Debug tab)

So basically, in Visual Studio.NET 2010:

  • create a new Console project,
  • add a reference to "System.ComponentModel.DataAnnotations" 4.0.0.0,
  • write the following code:

.

using System;

[assembly: System.Security.AllowPartiallyTrustedCallers()]

namespace TestingVaidationAttributeSecurity
{
    public class MyValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute
    { }

    [MyValidation]
    public class FooBar
    { }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("ValidationAttribute IsCritical: {0}",
                typeof(System.ComponentModel.DataAnnotations.ValidationAttribute).IsSecurityCritical);

            FooBar fb = new FooBar();
            fb.GetType().GetCustomAttributes(true);

            Console.WriteLine("Press enter to end.");
            Console.ReadLine();
        }
    }
}
  • Press F5 and you get the exception !

Press Ctrl-F5 (start without debugging), and it all works fine without exception...

The strange thing is that the ValidationAttribute will or will not be securitycritical depending on the way you run the program (F5 or Ctrl+F5). As illustrated by the Console.WriteLine in the above code. But then again, this appear to happen with other attributes (and types?) too.

Now the questions...

Why do I have this behaviour when inheriting from ValidationAttribute, but not when inheriting from System.Attribute ? (Using Reflector I don't find special settings on the ValidationAttribute class or it's assembly)

And what can I do to solve this ? How can I keep MyValidationAttribute inheriting from ValidationAttribute in an AllowPartiallyTrustedCallers assembly without marking it SecurityCritical, still using the new .NET 4 level 2 security model and still have it work using the VS.NET debug host (or other hosts) ??

Thanks a lot! Rudi

+3  A: 

Why do I have this behaviour when inheriting from ValidationAttribute, but not when inheriting from System.Attribute ? (Using Reflector I don't find special settings on the ValidationAttribute class or it's assembly)

This is because the System.ComponentModel.DataAnnotations assembly is conditionally APTCA i.e. it is marked with the following attribute.

[assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel = PartialTrustVisibilityLevel.NotVisibleByDefault)]

Something about the way Visual Studio starts the host process causes the CLR not to respect APTCA on this assembly even though the default AppDomain is fully trusted. This implies that all the types and methods in the DataAnnotations assembly are SecurityCritical. Since a security transparent type (MyValidationAttribute) cannot inherit from a security critical type (ValidationAttribute), this exception is thrown.

And what can I do to solve this ? How can I keep MyValidationAttribute inheriting from ValidationAttribute in an AllowPartiallyTrustedCallers assembly without marking it SecurityCritical, still using the new .NET 4 level 2 security model and still have it work using the VS.NET debug host (or other hosts) ??

It seems like this is a bug with the VS host, which is unfortunate for your situation. On the other hand, you should really be sure that you want your assembly to be APTCA. If it's necessary, then you have a couple of options.

  • You can leave your assembly as is. This is advantageous because in the most typical partial trust environment, ASP.NET, the DataAnnotations assembly will always be considered APTCA. Of course, you lose the ability to use the debugger in the VS hosting process.
  • You can mark your assembly C-APTCA as well. You'll be able to use the debugger in the VS hosting process, but consumers of your assembly in ASP.NET will need to add your assembly to the <partialTrustVisibleAssemblies> element in the web.config in order for it to be APTCA.
  • You could make your attribute SecurityCritical, so you'll be able to use the debugger and will not require any special configuration in ASP.NET, but all classes that use your attribute must also be critical.
David DeWinter
A: 

For some reason the site posted the text into a completely different question from the one that was on the page when I was writing - weird.

ZXX
What does IIS have to do with anything? This is a console app.
Sailing Judo