Delay Signing and When to Use It


In working with Shawn Farkas, a tester in the CLR team, he has a lot of good points about delayed signing, which I have gathered in this section. Most people who develop .NET applications know about the delay signing feature of the CLR. (If you don't, check out MSDN's "Delay Signing an Assembly" for more details.) Basically, delay signing allows a developer to add the public key token to an assembly, without having access to the private key token. Because the public key token is part of an assembly's strong name, assemblies under development can carry the same identity that they will have when they are signed; however, every developer doesn't have to have access to the private keys.

For instance, to get an assembly signed at Microsoft, we have to submit it to a special signing group. These are the only people who have access to the full Microsoft key pair. Obviously, we don't want to go through this process for every daily build of the framework, let alone for each developer's private builds. (Imagine the debugging process if you had to wait for a central key group to sign each build you created.) Instead of going through all this overhead, we delay sign our assemblies until we get ready to make a release to the public, at which point we go through the formal signing process. You'll learn more about this topic in Chapter 15, "Customer Service and Support."

A delay-signed assembly contains only the public key token of the signing key, not an actual signature. (That's because the person producing the delay-signed assembly most likely doesn't have access to the private key that's necessary to create a signature.) Inside the PE file that was produced, a delay-signed assembly has space reserved for a signature in the future, but that signature is just a block of zeros until the real signature is computed. Because this block is not likely to be the actual signature value of the assembly, these assemblies will fail to verify upon loading because their signatures are incorrect.

Obviously, it wouldn't be useful if a delay-signed assembly were completely unable to load. To work around this problem, you need to use the Strong Named tool (sn.exe) included in the .NET Fx tools to add assemblies to the skip verification list. The specific command line is as follows:

sn -Vr assembly [userlist]

Assembly is the name of the assembly to skip. In addition to referring to a specific assembly, Assembly can be specified in the form *,publicKeyToken to skip verification for all assemblies with a given public key token. Users is a comma-separated list of users for which verification is skipped. If this part is left out, verification is skipped for all users.

Caution

Use this option only during development. Adding an assembly to the skip verification list creates a security vulnerability. A malicious assembly could use the fully specified assembly name (assembly name, version, culture, and public key token) of the assembly added to the skip verification list to fake its identity. This would allow the malicious assembly to skip verification, too.


The Problem with This Command

What this command does is tell the runtime not to verify the signature on an assembly that has the given public key token (if you use the *,publicKeyToken format), or just on a specific assembly. This is a gigantic security hole. You can easily read public key tokens from any assembly that you have access to. If you run ILDasm on System.dll, inside the manifest, you find the following line:

.publickey = (00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 )

This corresponds to the public key assigned to any assembly that is standardized by ECMA/ISO. You can easily compute the token from this value, but an easier way to get it would be to look at ILDasm on any assembly that references mscorlib. For instance, looking at the manifest of System.Xml.dll under ILDasm shows the following lines:

.assembly extern System {   .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..   .ver 1:0:5000:0 } 

This code shows the ECMA/ISO public key token. It's easy for a malicious developer to write an assembly named System.dll, with an assembly version of 1.0.5000.00, and put the public key just extracted from System.dll into the assembly. He won't be able to compute a valid signature because he doesn't have access to the ECMA/ISO private key pair, but that hardly matters because you've turned off strong name verification for this particular public key token. All he has to do is install this assembly in place of System.dll in your GAC, and he now owns your machine.

For this reason, don't skip verification for assemblies unless you are developing them yourself, and be extra careful about what code is downloaded onto your machine that might claim to be from your organization.

Protecting Yourself from the Security Hole You Just Created

Even if you take these precautions inside your company, how can you be sure that someone external to your company cannot somehow disable checking the strong name on your assemblies and swap your assembly with an evil counterpart?

The short answer to this is that you can't. The skip verification list is stored in the registry under HKLM\Software\Microsoft\StrongName\ Verification\<asmName,publicKeyToken>, which is protected by an Access Control List (ACL) that contains both users and groups and the level of access that each has. Anyone can read an ACL, but only administrators can write to it. If a malicious developer manages to write a public key token into your user's skip verification list, one of two things has happened:

  • Someone has modified the ACL, allowing more write access to this key than usual.

  • The malicious developer is already an administrator on the machine.

If the first bullet is true, revert the ACL to allow only administrators to write to the key, thus closing the hole. If the second bullet is true, the malicious developer already owns your machine. As an admin, this malicious developer could conceivably replace the CLR with a hacked version that doesn't verify assembly signatures, or perhaps doesn't implement CAS. If you've gotten into this second situation, "game over, thanks for playing." The malicious person will already have control of your box and can do as he wants.

In summary, delay-signed assemblies increase security in development shops by reducing the number of people who need access to an organization's private keys. However, the requirement that delay-signed assemblies need to be registered in the skip verification list means that developers' machines are open to various forms of attack. Make sure that your developers are aware of the situation and don't overuse your skip verification list, to help make your machines more secure in these environments. Again, this is something that gets driven out of a CBT.



The Build Master(c) Microsoft's Software Configuration Management Best Practices
The Build Master: Microsofts Software Configuration Management Best Practices
ISBN: 0321332059
EAN: 2147483647
Year: 2006
Pages: 186

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net