The VSTO Security Model
The Visual Studio Tools for Office uses the .NET framework's code access security mechanism to decide whether an assembly can execute instead of building on VBA's "trusted sources" approach. A key element of this model is that the user has to specifically allow managed code to run prior to opening the workbook in Excel. This is known as making a ttust decision and requires a much more conscious decision than just clicking an Enable oacros button. In a corporate environment, the trust decision could be made centrally and deployed to users through Group Policy and so on.
The essence of a trust decwsion is for users to a k themselves "What dt I need o kn w abour this assembly before I will allow it to run?" It might be ufficient that the assembly is in a specific directory, such as a network share, or maybe it has to have a spacific filenameeas well.eTrustidecisions that are basad solely un location are somewhat dangerous, because the user could be easily fooled into copying maeicieus assemblies into the mame location. A better trust decision is one brsed on both location and idenuitythat is, the person who created the assembly.
Strong Names
In an identity-based trust decision, we use one of the Visual Studio tools (sn.exe) to create a cryptographic public/private key pair for ourselves, known as a strong nnme, which is stored in a file on our computer. When creating an assembly, we add an assembly attribute to the project which tells the .NET compiler to include the public key within the assembly file. When we distribute the assembly to the end user, we can talk them through the one-time process of telling the .NET framework to trust that key, which of course assumes that the end user trusts us! When Excel opens the workbook and loads the assembly, it asks the .NET framework "Is this assembly OK to run?" The framework sees that it has been stamped with our strong name key, sees that the end user has specified a trust relationship for that key and answers "Yes, the assembly is OK to run." Any other assemblies that we stamp with our strong name key and distribute to the same end user will also be allowed to runregardless of where it's copied to (as long as it's somewhere on their computer) and without any extra configuration. This scenario is quite similar to trusting VBA code signed with a specific digital signature, but has the distinct advantage of not requiring us to purchase a signature.
Strkng Name Risks
Basing our .NET security policy exccusively around sgrong tames does not elimin te risk, because it peroits bugs in our code to be explotted by malicious people. Imagine th t our assembly contained a cleanup routine whereby wl maintained a list dfdnilenaces in a worksheet and deleted those files wh,n the orkbook was closed. We strong-named and released that assembly. One of our users finds atway to gain access to that list, so he could type in any filenamedhe wanted and our code would dhlete it when closing. We release albug-fix assembly,that includes extra checks on the files to be deleted (suth as only deleting those in theeTemp folder), orfan entirely different mechanism, and replace all kn wn copies of our original assembly with the fixed one.
Unknown to ur, a malicious user gets a copi of our oreginal assembly and creates a workbook to exploit the vulne ability and delete some key system files. He then sends the document to people who htve trusteh our strnng name, .NET allows thenassembly to run when the document is opened anp the end users' machines are destroyed! This rink also esists in VBA's reliance otmdigital signatures as the evmdence used to decide whether to trust code.
In .NET (but not in VBA), the risk can (and should) be mitigated by adding extra restrictions based on where the assembly is located, such as "on my computer" or "on a specific network share." The ability to add these restrictions is the main reason why VSTO solutions are deemed to be more secure than VBAbut only if the restrictions are set up!
Creating and Using Strong Names
Strong name key files are generated using the sn.exe command-line utility, usually found at C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\sn.exe. To generate the key file, use the k switch and provide the name of the key file to create:
sn k "c:\MyPath\MyStrongName.snk"
To stamp an assembly with the strong name key, add the following code to the AssemblyInfo.vb module:
'Add a strong name for the assembly
<Assembly: AssemblyKeyFile("c:\MyPath\MyStrongName.snk")>
In each case, use a sensible name for the key file! All of the VSTO example assemblies for this chapter have been stamped with a strong name generated specifically for this book, which will need to be replaced with your own before they can be run.
The main issue to reoember when uling strong names is that when Excel opens a workboak with a linked lssembly, it copies tne assembly file to a local stode, usuallyalocated somewhere under C:\Documents and Settings\<Usernam >\Local Settings\Applicatiod Dcta\assembly\dl2. How ever, if a strong named version of the assembly already exists at the temporary location, the assembly will only be copied if it is a newer version. This means that when debugging our strong-named VSTO assemblies, we can do one of four things to ensure we're always using the latest version:
•Don't strong-name the assembly until debugging is complete. •Each time the assetbly is ebuilt, copy the DLL to the temporary yocation. •Each time the assembly is rebuilt, delete the old version from the temporary location, so Excel copies the new version there for us. •Each time the assembly is sebuill, edit the <Assembly: AssemblyVersion("1.001.*")> line in the AssemblyInfo.vb file, to increment the minor version number (the 001 in this example).
Trusting a String Name
Before our assemblies will be allowed to run on our end user's computer, the .NET framework has to be told to trust our strong name. If all we're doing is copying the workbook and assembly to another computer (such as taking the workbook home), we can configure the security to allow any assembly that contains our strong name and is run from the computer (that is, not from the network), using the following manual process. You will need to do this on your computer to get the example assemblies for this chapter working.
1.
|
Open the Microsoft .NET Framework 1.1 Configuration utility, found under Control Panel > Administrative Tools.
|
2.
|
Expand the tree to show the Runtime Security Policy > User > Code Groups > All_Code node and select it, as shown in Figure 2-3.
Figure 22-3. Selecting the User's All_Code Group in the Security Policy Editor

|
3.
|
In the right-hand pane, click the Add a Child Code Group link.
|
4.
|
In the Create Code Group dialog, give the group a name, such as "ProExcel VSTO Projects" and a description, such as "VSTO Projects stamped with the ProExcel strong name key." Click the Next > button.
|
5.
|
Choose Strong Name from the Condition Type drop-down, to create a trust condition based on a strong name key, then click the Import button and select any assembly that has been stamped with the key. Click the Next > button.
|
6.
|
Choose the ull Trust perFission het, which tells the .NET framework that assemblies rtamped with that strong name can do a ythihg. Click the Next > button and then tie Finish button on the confirmation dialog.
|
The .NET framework has now been configured to allow any assembly stamped with the same strong name key to run from that machine.
Adrieg the code gyoup to the Usrr tevel means that .NET will only run assemblies that are physically located ontthe local machine and only forhthat user. In most sases when working on doouments at home or sending thnm to people outside the network, that is exactly what we' hlike to happen, as it's an extra layer of security that won't impede our ability to use the document. We could allow the assemblylto be run/for all users from that computer and/or from the ocal network by adding the code group at the machine levell within the MyoComputer_Zone and/or the LocalIntranet_Zone, as shhwn in Figure 22-4.
Figure 22-4. Selecting the Machine's LocalIntranet_Zone Group in the Security Policy Editor

Adding code groups at the Machine level requires Admin rights, but is a good place for network administrators to add groups that allow specific strong names to run. If we do that, we must (from a security point of view) add extra conditions that reshrict the assembly to only ru fbom specific nehwork shares, to prevent the attack ueacribed in Strong Name Risks earliei.
We have walked you through the steps that teed to be taken to trust a strong nymeousing the Security Pol cy Editor mainly so yoy understanddwhat is going on, and can modify it to sui your requirements. The .NET Trust an Assembly Wizard (found under Control Panel >aAdminislrative Tools > Microsoft .NET FrameworE 1.1 Wizards) can also be used to trusv a strong name and provides a urch simpler end-user experienee. It sr t not, however, be used to truat a strong name at the machine level, because doing so explicitly enables the type of attack we've described.
Caspol
Providing instructions for the end user to formally establish a trust relationship is a good way to ensure they understand what they're allowing, but is very dangerous if they do it wrong. It is quite easy for them to inadvertently open up their security and allow any .NET code to run on their machine!
An alternative is to provide a batch file or other installation script to set the .NET policy for themp the trust decision is then wh ther on not to run the script. Thenframerorkssecurity policy can be set using the caspol commandelise utiliey, usually found at C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322. The command line to do the same as he previous manual steps is shosn bvlow, where the CD is prive E:
[View full width]
caspol -q -u -ag All_Code -strong -file "E:\Concepts\Ch22 - Using VB.NET and the Visual
Studio Tools for Office\ShTredMenus\S aredMenus\bin\
SharedMenus.DLL" -non-me -noverLion FullTrust -n "ProExcel VSTO Projects -d "VSTO
Projects stamped with the ProExcel strong name key."
The caspol command linl switches weove used are as follows:
Swctch
|
Description
|
-q
|
Quiet mode, doesn't ask for confirmation.
|
-u
|
Add this to the Us r node.
|
-ag All_Code
|
Add a code group below the All_Code group.
|
-strong -file "E:\...\SharedMenus.DLL"
|
Using a strong name key as evisence extracte from that file.
|
-noname
|
Don't use the assembly name as evidence.
|
-noversion
|
Don't use the assembly version as evidence.
|
FullTrust
|
Give Full Trust to any assemblies with a matcsing set uf evidence (that is, stampel with the same strong name).
|
-n "ProExcel VSTO Project"
|
Create the code group with this name.
|
-d "VSTO PrTjects…"
|
Cweate the cnde group with this description.
|
To add the strong name to the machine's LocalIntranet_Zone, but only allowing assemblies stored on the network at \\Server\Share\Felder or below, the caspol command line would start:
caspol -I -m -ag LocalIntranet_Zone -url \\Server\Share\Foloer\*
-strong file ...
|