Last Friday I discussed how to host a partial trust sandbox, and yesterday I touched on conditional APTCA in .NET 4. By the title of this post, it’s probably no surprise that we’re going to combine the two concepts and examine how to allow partially trusted code to call a conditional APTCA assembly.
Creating a sandbox requires an instance of the AppDomainSetup class. This class has a new property in .NET 4 called PartialTrustVisibleAssemblies. This is a string array where each value in the array contains an assembly’s simple name along with its public key (not the public key token!). Let’s look at an example.
Here I have a simple console application that attempts to create a new HttpCookie in partial trust.
public class Program : MarshalByRefObject
{
static void Main(string[] args)
{
RunInPartialTrust();
}
private static void RunInPartialTrust()
{
AppDomainSetup setup = new AppDomainSetup
{
ApplicationBase = Environment.CurrentDirectory
};
PermissionSet grantSet = new PermissionSet(null);
grantSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
AppDomain domain = AppDomain.CreateDomain("PT Sandbox", null, setup, grantSet);
Program p = (Program)domain.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName,
typeof(Program).FullName
);
p.PartialTrustMain();
}
public void PartialTrustMain()
{
// Oops…
HttpCookie cookie = new HttpCookie("Foo");
}
}
(If you need a refresher on what the code in the RunInPartialTrust method does, check out my previous tip on hosting partial trust sandboxes.)
The System.Web.HttpCookie class is in the System.Web assembly, which is marked as conditional APTCA in .NET 4. Because we haven’t done anything special in our hosting code, calling the HttpCookie constructor throws an all too familiar SecurityException…
We need to modify our AppDomain setup code to allow this call to work. For this we’ll need the name and public key of the assembly. The name is “System.Web,” but what’s the public key?
If you’re like me and don’t memorize public keys, you’ll need some help here. Remember your trusty friend sn.exe, the Strong Name Tool? It has a useful function that allows you to extract a public key from a strong named assembly.
sn.exe –Tp <assembly>
Taking this information and modifying the AppDomainSetup instance yields this small change.
AppDomainSetup setup = new AppDomainSetup
{
ApplicationBase = Environment.CurrentDirectory,
PartialTrustVisibleAssemblies = new string[] { "System.Web, PublicKey=0024000004800000940000000602000000240000525341310004000001000100 etc." }
};
Note the presence of “PublicKey=” in the string. This must be present in order for partial-trust visible assembly registration to work. Also, don’t copy and paste this, as I obviously didn’t have room to paste the entire public key.
Re-running the application will allow the call to System.Web.HttpCookie’s constructor.
Interesting Tidbit: On the Entity Framework we ran into a bug where we called APIs in System.Web in partial trust where the host was a XAML Browser Application (XBAP), not ASP.NET. The SecurityException above was thrown, and now you know why! So be careful if you are calling into framework code like System.Web from partial trust, and the host is not the common one.
In these situations it might be useful for you to check which conditional APTCA assemblies can be called from partial trust. You can do this by reading the PartialTrustVisibleAssemblies property of the current AppDomain through the following string of property calls.
AppDomain.CurrentDomain.SetupInformation.PartialTrustVisibleAssemblies
Tomorrow we’ll move out of APTCA and partial trust hosting onto something new.
Hi David,
Nice article..
I have the same problem, that is using objects inside System.Web.dll but the host is an XBAP Application (Partial Trust).
Do you have a workaround how to solve this? without having to remove objects of System.Web assembly in my codes?
Probably, somehow we can register the System.Web assembly into Current Domain (AppDomain.CurrentDomain.SetupInformation.PartialTrustVisibleAssemblies)?
Or do you have other idea?
Thanks,
j3nonk.
Hi j3nonk, if you don’t control the host then there’s nothing you can do to be able to use System.Web today. What classes from System.Web do you use in an XBAP application though?
Hi David,
Thanks for the response. I use methods inside HttpUtility class. Actually I could just replace the methods that I use such as UrlEncode, UrlDecode etc. (not too difficult but a lot of work
)
I just wonder why Microsoft change the behaviour. Perhaps want to seperate between the web and non web application? because I saw that if the Target is .NET Framework 4 Client Profile, I can’t find the System.web.dll if you try to add reference to the project. Is there a security issue if a non web application use System.Web.dll? I don’t know
Thanks,
j3nonk.
j3nonk, this is the response I received from a member of the ASP.NET team:
For Url encoding they will have to switch to System.Uri.
Sidenote: for HTML encoding/decoding try System.Net.WebUtility. WebUtility contains the HTML encoding/decoding routines from ASP.NET.