Trusting the Document
So far we have been talking only about trusting the customization assembly. That makes senseit is, after all, the container of the code that is going to run. However, there is something quite unusual about customized documents that makes them very different from traditional forms-based applications. Here is a silly but illustrative example. Suppose you write a customization for a budget spreadsheet that has two named ranges that have event handlers that handle their double-click events as shown in Figure 19-9.
Figure 19-9. A budget spreadsheet that could be exploited by an attacker.
[View full size image]

Trusting Just Office Documents
Consider the following policy scenario: You want to deploy your customized document on an internal Web server. The customization is strong named, and you have an Enterprise policy that grants full trust to code with that strong name on that Web server. Suppose the policy looks like this:
EnterpriseAll CodeFull trustURL: http://MyServer/customizations/* No permissionsFoo Corporation Strong NameFull trust, level-final
This will fully trust the customization assembly because the level-final attribute on the strong-name code group will prevent the other three policy levels from further restricting the assembly's granted permission set.But what about the document? The document needs to be trusted, too. In this example, the Enterprise policy level will fully trust the document by virtue of that root All Code code group. But the out-of-the-box Machine policy level will only see that the document is in the LocalIntranet Zone code group, and not grant full trust.We could fix up this policy by making the URL code group above also grant the full trust permission set and make it level-final. However, that represents a pretty serious weakening of the policy. That would then say that all documents and code on that Web site, regardless of whether it was associated with a customization or not, whether strong named or not, are fully trusted. Really what we want to say is "all code signed with the strong name on the server, and all documents on the server are fully trusted."We need a new membership condition that only matches Word and Excel documents. Fortunately, there now is such a membership condition, the aptly named Office Document Membership Condition. Membership conditions are represented by objects in the .NET security policy, and the assembly containing those objects has to be in the Global Assembly Cache (GAC). If it is not already, use gacutil.exe to install msosec.dll into the GAC:
You can now create a Custom security policy that trusts all Word and Excel documents on a particular server. Custom membership conditions are represented by XML files. The Office Document Membership Condition has a simple representation in XML; it contains just the name of the membership condition type and the strong name of the assembly containing it, as shown in Figure 19-10.
> Gacutil -i MSOSec.DLL
Microsoft (R) .NET Global Assembly Cache Utility. Version 2.0
Copyright (C) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
Figure 19-10. Creating a code group based on the Office Document Membership Condition.

Why Is MSOSec Not in the GAC by Default?
The other VSTO assemblies are put in the GAC for you automatically, so why not this one? There is a good reason.