Loading an Assembly as a Byte Array

One of the various ways that you can load an assembly is by supplying the raw bytes of an assembly as a byte array.  The security identity of an assembly loaded this way turns out to be different than if you were to load the same assembly by name or by file.  In the case that you load an assembly with its name or its file name, we generate all the evidence that you normally think of — such as Zone, Site, Url, StrongName, Publisher, etc.

Now, when we’ve loaded via a byte array, a lot of that information is not available to us.  Specifically, we don’t know the location based evidence for the assembly, like Zone, Site, and Url.  Since the standard security policy makes nearly all of its trust decisions based upon this location evidence, there’s a bit of problem when attempting to figure out what grant set this assembly should get.

What ends up happening is that the CLR will consider the new assembly as having the same security identity of the assembly that loaded it.  Unless the new assembly is loaded with explicit evidence, we will give it the same evidence as the assembly doing the loading.  This is analogous to the Reflection.Emit scenario, and it makes a lot of sense in the case that this extra assembly is really an extension of the loading assembly, such as when the byte array was stored as a resource in the loading assembly.

The scenario where you really need to be aware of this is when you’re a fully trusted assembly which is loading a byte array containing a lower trust assembly.  In that case, it’s very likely that you do not want the default behavior of letting the byte array have the same security identity as you.  Instead, the Assembly.Load method that takes both a byte array and Evidence should be used.  This will let you supply the specific security identity of the lower trust byte array to use when resolving policy for the assembly.

Comments (1)

  1. It’s unfortunate that loading with evidence requires a high privilege permission, rendering the technique essentially useless for partially trusted code that needs to further restrict the permissions of code that it loads dynamically.  If the method didn’t require SecurityPermissionFlag.ControlEvidence but instead resulted in a permission grant at the intersection of the loader permissions and the evidence-based permissions, even partially trusted callers could benefit.