Wednesday, August 21, 2013

Custom assemblies with ISerializable classes running in ASP.NET medium trust applications

The problem.

  • Suppose you have some common code that want to share between your projects. So you placed that code in a Class Library project, create an assembly and reference it in your projects.
  • Let’s also suppose that one or more classes in that assembly implements ISerializable interface;
  • Finally, imagine that we have a web-application, which uses this assembly and this application is run in medium-trust environment (by the way, most shared hosting services will run your application in medium-trust security level).
If you meet all of the above terms you are likely to encounter with the same problem, which we faced not so long ago with our EasyQuery ASP.NET assemblies.
Namely, when accessing a Web page that uses code from such assembly you will see something like the following:

Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: Inheritance security rules violated while overriding member: 'Korzh.EasyQuery.DataModel.System.Runtime.Serialization.ISerializable.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.

The reason of the problem

Medium trust level of ASP.NET web-application requires from application’s code to be security transparent. We should note that since version 4.0. NET framework uses a new (Level 2) model code access security (CAS). For more information on these changes please read this article.
Among other changes Level 2 CAS introduces new requirements to security-transparent code (you can read more about them here).

The problem is that GetObjectData() method required to implement ISearializable interface is marked with a SecurityCritical attribute and so this piece of your code "breaks" the transparency for the whole assembly.

The solution

We tried different approaches to solve this problem. Nothing helped.
The only working solution we found for now is to set the following two assembly-wide attributes in AssemblyInfo.cs file for your project:

[assembly: SecurityRules(SecurityRuleSet.Level1)]
[assembly: AllowPartiallyTrustedCallers]

So the solution is simply to lock your assembly into the .NET Framework 2.0 rules (level 1 transparency) and just ignore new security rules introduced in .NET 4.0

Unfortunately currently we can say nothing about any disadvantages of this solution. I'm going to publish an update to this post if we encounter some problem with it.

Any comments, notes, suggestions or links to other solutions of the described problem are welcome!

See also

Here are the links to articles where you can find more information about code access security and trust levels in ASP.NET applications: