The VSTO Security ModelThe 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 trust decision and requires a much more conscious decision than just clicking an Enable macros 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 decision is for users to ask themselves "What do I need to know about this assembly before I will allow it to run?" It might be sufficient that the assembly is in a specific directory, such as a network share, or maybe it has to have a specific filename as well. Trust decisions that are based solely on location are somewhat dangerous, because the user could be easily fooled into copying malicious assemblies into the same location. A better trust decision is one based on both location and identitythat is, the person who created the assembly. Strong NamesIn 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 name, 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. Strong Name RisksBasing our .NET security policy exclusively around strong names does not eliminate risk, because it permits bugs in our code to be exploited by malicious people. Imagine that our assembly contained a cleanup routine whereby we maintained a list of filenames in a worksheet and deleted those files when the workbook was closed. We strong-named and released that assembly. One of our users finds a way to gain access to that list, so he could type in any filename he wanted and our code would delete it when closing. We release a bug-fix assembly that includes extra checks on the files to be deleted (such as only deleting those in the Temp folder), or an entirely different mechanism, and replace all known copies of our original assembly with the fixed one.Unknown to us, a malicious user gets a copy of our original assembly and creates a workbook to exploit the vulnerability and delete some key system files. He then sends the document to people who have trusted our strong name, .NET allows the assembly to run when the document is opened and the end users' machines are destroyed! This risk also exists in VBA's reliance on digital signatures as the evidence 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 NamesStrong 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: To stamp an assembly with the strong name key, add the following code to the AssemblyInfo.vb module: 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 remember when using strong names is that when Excel opens a workbook with a linked assembly, it copies the assembly file to a local store, usually located somewhere under C:\Documents and Settings\<Username>\Local Settings\Application Data\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 assembly is rebuilt, copy the DLL to the temporary location.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 rebuilt, 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 Strong NameBefore 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.
The .NET framework has now been configured to allow any assembly stamped with the same strong name key to run from that machine.Adding the code group to the User level means that .NET will only run assemblies that are physically located on the local machine and only for that user. In most cases when working on documents at home or sending them to people outside the network, that is exactly what we'd like to happen, as it's an extra layer of security that won't impede our ability to use the document. We could allow the assembly to be run for all users from that computer and/or from the local network by adding the code group at the machine level, within the My_Computer_Zone and/or the LocalIntranet_Zone, as shown in Figure 22-4. Figure 22-4. Selecting the Machine's LocalIntranet_Zone Group in the Security Policy Editor![]() CaspolProviding 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![View full width]caspol -q -u -ag All_Code -strong -file "E:\Concepts\Ch22 - Using VB.NET and the Visual ![]() ![]() The caspol command line switches we've used are as follows:
|