<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>HD DVD / Randomness... : Visual Studio</title><link>http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx</link><description>Tags: Visual Studio</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Sliced bread ain’t got nuthin’ on this!</title><link>http://blogs.msdn.com/ptorr/archive/2007/10/02/sliced-bread-ain-t-got-nuthin-on-this.aspx</link><pubDate>Tue, 02 Oct 2007 21:49:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5246358</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/5246358.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=5246358</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=5246358</wfw:comment><description>&lt;p&gt;Forget being the best thing &lt;em&gt;since&lt;/em&gt; sliced bread – this is the best thing &lt;em&gt;ever&lt;/em&gt;. Well maybe not &lt;em&gt;quite &lt;/em&gt;that good, but it's still darn cool!
&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:14pt"&gt;Finally – &lt;span style="color:red"&gt;&lt;strong&gt;FINALLY!&lt;/strong&gt;&lt;/span&gt; – you can get &lt;a href="http://blogs.msdn.com/webdevtools/archive/2007/03/02/jscript-intellisense-in-orcas.aspx"&gt;decent IntelliSense for JScript inside Visual Studio&lt;/a&gt;! 
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Holy hotcakes, Batman! This is so awesome you have to &lt;a href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;download Visual Studio 2008 Beta 2&lt;/a&gt;
		&lt;strong&gt;right now&lt;/strong&gt; and try it out. 
&lt;/p&gt;&lt;p&gt;Back when I was on the script team, we couldn't get any features into Visual Studio (much to the chagrin of our customers) because all the hype was around ASP.NET. The rich client was dead. It was all about the server. Nobody needed client-side script any more. Everything was a web form post-back.
&lt;/p&gt;&lt;p&gt;But now that AJAX and Silverlight and all these other buzzwords are suddenly important, people taking notice of the little script language that could. 
&lt;/p&gt;&lt;p&gt;Congrats and thanks to the Visual Web Developer and JScript teams – at last, JScript is getting some of the respect it has always deserved! :-)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5246358" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HDi/default.aspx">HDi</category></item><item><title>Inheritance Demands for Interfaces</title><link>http://blogs.msdn.com/ptorr/archive/2005/01/16/353816.aspx</link><pubDate>Sun, 16 Jan 2005 08:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:353816</guid><dc:creator>ptorr</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/353816.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=353816</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=353816</wfw:comment><description>
    &lt;div class="Section1"&gt;
      &lt;p&gt;
        &lt;span&gt;I'm cheating here by re-posting an e-mail I sent the other day... but hey, you don't expect me to come up with &lt;span style="font-weight:bold;"&gt;new&lt;/span&gt; content for this blog do you? :-)&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Here is a deliberately contrived example of why you might need to protect interfaces with inheritance demands.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Say I have declared an interface, &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IWhichFileShouldIDelete&lt;/span&gt;, that has a single property &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;string&lt;/span&gt; &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileName&lt;/span&gt; that returns the name of a file to delete.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;I also have a fully-trusted object, &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileDeleter&lt;/span&gt;, which has a &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileToDelete&lt;/span&gt; property and a &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;DeleteFile&lt;/span&gt; mehod. The &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileToDelete&lt;/span&gt; property takes an &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IWhichFileShouldIDelete&lt;/span&gt; object that is then queried in the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;DeleteFile&lt;/span&gt; method. (I already said this was contrived, right? :-) ).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;The problem with this design is that the way in which the interface / object interact allows partially-trusted code to delete sensitive files. This is because the actual implementation of the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileName&lt;/span&gt; property doesn't require any special permissions (it just returns a string), and when the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;DeleteFile&lt;/span&gt; method is called there is no code from the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IWhichFileShouldIDelete&lt;/span&gt; object on the stack, so any stack walks for &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileIOPermission&lt;/span&gt; will succeed. This is bad because now partially-trusted code can cause random files to be deleted.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;As an example, you might have code like this:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;&amp;nbsp;&lt;/span&gt;
      &lt;/p&gt;
      &lt;div style="border-top:solid 1pt #99CCFF;padding-top:1pt;border-bottom:solid 1pt #99CCFF;padding-bottom:1pt;border-right:solid 1pt #99CCFF;padding-right:4pt;border-left:solid 1pt #99CCFF;padding-left:4pt"&gt;
        &lt;div style=""&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;// Inside fully-trusted code...&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp;IWhichFileShouldIDelete file &lt;span style="color:#008080;"&gt;=&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;new&lt;/span&gt; GetTheFileName&lt;span style="color:#008080;"&gt;();&lt;/span&gt; &lt;span style="color:#008000;"&gt;// See below&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp;FileDelete deleter &lt;span style="color:#008080;"&gt;=&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;new&lt;/span&gt; FileDeleter&lt;span style="color:#008080;"&gt;()&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;// Here is where the design falls apart...&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;&amp;nbsp;&amp;nbsp;deleter&lt;span style="color:#008080;"&gt;.&lt;/span&gt;FileToDelete &lt;span style="color:#008080;"&gt;=&lt;/span&gt; file&lt;span style="color:#008080;"&gt;;&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;// Note the call-stack will be 100% FT code at this point&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp;deleter&lt;span style="color:#008080;"&gt;.&lt;/span&gt;DeleteFile&lt;span style="color:#008080;"&gt;();&lt;/span&gt; &lt;span style="color:#008000;"&gt;// Deletes c:\boot.ini -- Ooops!&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;// ----------&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;// Assembly boundary&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;// ----------&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;// Inside partially-trusted code...&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#0000FF;"&gt;&amp;nbsp;&amp;nbsp;class&lt;/span&gt; GetTheFileName &lt;span style="color:#008080;"&gt;:&lt;/span&gt; IWhichFileShouldIDelete&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;string&lt;/span&gt; FileName &lt;span style="color:#008080;"&gt;{&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;get&lt;/span&gt; &lt;span style="color:#008080;"&gt;{&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;return&lt;/span&gt; &lt;span style="color:#800000;"&gt;@"c:\boot.ini"&lt;/span&gt;&lt;span style="color:#008080;"&gt;; } }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;span&gt;In this scenario, the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IWhichFileShouldIDelete&lt;/span&gt; interface should only be implemented by fully-trusted code, because only fully-trusted code should be able to say which files are deleted. To ensure that only fully-trusted code can implement &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IWhichFileShouldIDelete&lt;/span&gt;, you have to put an &lt;a style="text-decoration:none;" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconInheritanceDemands.asp"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;inheritance demand&lt;/span&gt;&lt;/a&gt; on the interface itself for unrestricted permissions (or maybe just unrestricted File I/O). This is necessary because the CLR's security system is based around &lt;span style="font-weight:bold;"&gt;code &lt;/span&gt;(stack walks), not &lt;span style="font-weight:bold;"&gt;information&lt;/span&gt; (data flow analysis).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;A really cool (but most likely completely impractical) thing to add to the CLR would be a "forward" demand -- "Make sure the code &lt;span style="font-style:italic;"&gt;that I am about to call&lt;/span&gt; has such-and-such a permission" -- to complement the current "Make sure the code &lt;span style="font-style:italic;"&gt;that called me&lt;/span&gt; has such-and-such a permission" we get from normal demands. &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;For now, the best we can do is to make sure bad people can't implement methods that they shouldn't be allowed to, and we can accomplish that with inheritance demands.&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=353816" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Changing Abstractions in an Object Model is Hard</title><link>http://blogs.msdn.com/ptorr/archive/2004/12/18/325109.aspx</link><pubDate>Sun, 19 Dec 2004 04:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:325109</guid><dc:creator>ptorr</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/325109.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=325109</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=325109</wfw:comment><description>
    &lt;div class="Section1"&gt;
      &lt;p&gt;
        &lt;span&gt;Up until recently, I was working on a rather large spec for an as-yet-un-announced product. The majority of the spec consisted of class definitions and the details surrounding their interactions, but there was also a rather large conceptual component to the spec as well; you can't really dive into 50+ pages of object model specifications without knowing about the kinds of abstractions involved, how the different pieces fit together, and so on. I also spent time on a 30+ page threat model for the feature, but that's another story :-)&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Anyway, I can't talk about this feature specifically (because it's not announced yet), but let's pretend the spec was for an object model for a car. When deciding how to design an object model for something complicated like a car, there are a lot of things you need to consider, such as:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;How accurately do you want to represent the modelled object?&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;How easy do you want it to be for "typical" developers to use?&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;How extensible does it need to be for "advanced" developers to customise?&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;How performant / version-resilient does it need to be?&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;And so on&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;In particular, you can probably tell right off the bat that the first two considerations are at odds with each other -- to accurately model a car, you would need to have objects representing every component of the car, perhaps even including the individual nuts and bolts holding the thing together (or, depending on the task at hand, maybe even the types of materials from which those nuts and bolts were fabricated). But to make a car object model easy to use, you want to simplify (abstract away) many of the details so that the developer has less concepts to understand (after all, they're a computer programmer, not an auto mechanic) and so that they can "discover" and use the features of the object model in a natural way.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;For example, we'd rather write:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;text-indent:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;myCar.Color = Color.Red&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;than, say:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;text-indent:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;myCar.Body.Panels.Exterior.PaintJob.MajorColor = Color.Red&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;But on the other hand, we'd also rather write:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;text-indent:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;myCar.Tyres.Width = 18&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;than, say:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;text-indent:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;myCar.TyreWidth = 18&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;when you consider all the other properties of tyres that might be desirable.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;So before you start designing the object model, you want to decide on your major abstractions (well, actually it's more of an iterative process, but anyways...). What details are necessary (&lt;span style="font-style:italic;"&gt;the colour of the car&lt;/span&gt;), and what details can be glossed over (&lt;span style="font-style:italic;"&gt;only the outer panels are painted&lt;/span&gt;)? What pieces of functionality can be logically grouped together (&lt;span style="font-style:italic;"&gt;make and model of car&lt;/span&gt;), and what pieces need to be separated (&lt;span style="font-style:italic;"&gt;car colour and tyre width&lt;/span&gt;)?&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Now one of the abstractions we decided to make in this particular spec was something akin to saying that a car and its engine were one and the same thing. You couldn't have a car without an engine, and you could only have one engine in your car. Additionally, there weren't really any interesting properties of the engine (in our scenarios) so it didn't make sense to split off a separate &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Engine&lt;/span&gt; type. Nevertheless, there were still a few interesting things about engines that we needed to expose (like the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Start&lt;/span&gt; method or the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Stalled&lt;/span&gt; event) that we attached to the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Car&lt;/span&gt; object. &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Put another way, when speaking in plain English about their cars, people tend to say things like "I started my car" or "My car stalled the other day," rather than "I started the engine in my car" or "My car's engine stalled." Mapping object models to the way people &lt;span style="font-style:italic;"&gt;think&lt;/span&gt; about The Real World is often more important than actually modelling The Real World. &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;So we have a design around one engine per car, and the world is a happy place. But then Someone Important says we have to support the new "hybrid" cars in our design -- those that have both an electric motor and an internal combustion engine (like the &lt;a style="text-decoration:none;" href="http://www.toyota.com/prius/"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;Toyota Prius&lt;/span&gt;&lt;/a&gt; or the &lt;a style="text-decoration:none;" href="http://automobiles.honda.com/models/model_overview.asp?ModelName=Civic+Hybrid"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;Honda Civic Hybrid&lt;/span&gt;&lt;/a&gt;). Now, we've always known that hybrids existed, but we deliberately kept them out of our original design because (i) they are an edge-case scenario and (ii) they overly complicate the design for the rest of the users. (We like to have a "pay for play" approach at Microsoft -- you only pay the tax for advanced / complicated features if you want to use them. Never make the simple case overly complicated just to support some bizarre non-standard scenarios unless there's no other way around it).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;So, we grudgingly add Hybrids to our model. And to be safe, rather than move from one engine to two, we abstract a bit more and say that you can have a collection of arbitrary types of engines with an arbitrary length. Need thirteen engines in your car? No problem. And we also need to make our concrete &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Engine&lt;/span&gt; class (which was an internal implementation detail of the old code) into a public &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngine&lt;/span&gt; interface that anyone can write a custom implementation of. Need an engine that channels psychic power into kinetic energy? No problem!&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Now we can have a &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;PetrolEngine&lt;/span&gt; class and an &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;ElectricEngine&lt;/span&gt; class and stick them both inside a collection of &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngine&lt;/span&gt; objects inside a single &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Car&lt;/span&gt; object. Cool!&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;But there is a problem: what happened to the object model?&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;In the simple (non-hybrid) case, we go from:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;myCar.Start()&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;to:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;myCar.Engines[0].Start()&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;and in the more generic case we go to:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;for each (engine in myCar.Engines)&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-top:0pt;margin-left:36pt;"&gt;
        &lt;span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;
          &lt;/span&gt;
          &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;engine.Start()&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;But realistically, what will happen is that developers will always use the first code snippet. Why? Because all the cars in their system will only ever have one engine, and the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;for each&lt;/span&gt; loop just looks ugly. Why loop through a collection that only has one element? And the program will work fine -- maybe for years -- until the first time someone plugs a hybrid into the system and it crashes [hah, a pun!] because the second engine isn't started.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;The other (more important) thing is that we don't actually know how hybrids (or future variations thereof) will work. Do we &lt;span style="font-weight:bold;"&gt;really&lt;/span&gt; want to start both engines at the same time? Or do we want to just ask the hybrid to "start" and have the engines communicate with each other and decide when each one should kick in? What we need is another abstraction over the basic "collection of engines" that hides this detail. But since we don't know how the engines work, we must define some abstract interface that allows us (the car object model builder) to provide the developer (object model user) to deal with engines in an abstract way, whilst allowing the engine providers to plug in whatever features they need to make their engines work.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;So now we have another new interface, &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngineCollection&lt;/span&gt;, that exposes things such as the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Start&lt;/span&gt; method and &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Stalled&lt;/span&gt; event and provides some way for interested clients to dig deeper into the individual &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngine&lt;/span&gt; elements of the collection if they need to. We then provide a default implementation of &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngineCollection&lt;/span&gt; that supports a single petrol engine and simply forwards all the interface members on to that engine. We might call it &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;SinglePetrolEngineCollection&lt;/span&gt; or some such thing, and have a nice easy way for clients to get an instance of it (or even just assume it's the one they want if they call the default &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Car&lt;/span&gt; constructor and don't supply their own implementation). &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Manufacturers of hybrids can supply their own custom &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngine&lt;/span&gt; implementations (one for the petrol engine, one for the electric engine, one for the &lt;a style="text-decoration:none;" href="http://www.imdb.com/title/tt0088763/"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;Mr. Fusion engine&lt;/span&gt;&lt;/a&gt;, etc.) and then their own &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngineCollection&lt;/span&gt; implementations that do clever things inside the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Start&lt;/span&gt; method to decide which engine(s) to start, and so on. Then when users want to create hybrids they simply use the Car constructor that accepts a custom &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IEngineCollection&lt;/span&gt; implementation, and they're good to go.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Now to get rid of the "complexity tax" we can put back our original &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Car.Start&lt;/span&gt; method, which is just a simple wrapper that defers to &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Car.EngineCollection.Start&lt;/span&gt;, and the developer who just wants to start the stupid car can do so without worrying about multiple engines or about writing bugging code based on bad assumptions.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;So why didn't we do this in the first place? We knew the problem existed, and there was a way to solve it that still followed the "pay for play" model.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;One answer is that basically you don't want to make your system more complicated than it needs to be. Complications lead to bugs, and unnecessary complications lead to unnecessary bugs. Having lots of "pluggable" components (interfaces, abstract classes) makes it hard to reason about the system (and to threat model it!) because you can't be sure what any given extension will do. Allowing multiple, non-communicating developers to change the heart of the system also leads to reliability problems and other concerns that can't be tested or fixed by the OM developer (the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;AcmeEngine&lt;/span&gt; and the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;ContosoEngine&lt;/span&gt; both assume they have exclusive access to the fuel tank and don't co-ordinate their accesses to it, for example).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Another answer is that although we have hidden the complexity at a source-code level, we still have to expose it at the documentation level. The developer only needs to write &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;myCar.Start&lt;/span&gt; to start her car, but if she ever looks at the documentation for the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Start&lt;/span&gt; method she will be rudely yanked into a world of engine collections and layered abstractions and other such nonsense that she really has no desire to know about. Or, if she is just getting started with the object and starts to read the conceptual overview, there will be far too many things obscuring the basic design that she won't be able to see the forest for all the trees. This is a real concern, since documentation is incredibly hard to write and minimising the number of concepts a developer must grasp to use an object model is crucial to making it usable.  &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;So I'm not sure what the point of this post was... ;-) Maybe it helps explain some of those really complicated Microsoft APIs where everything is an abstract interface and there are fifty different moving parts, none of which you really need to understand to use the API, but you're confused by them anyway.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Or maybe it just re-enforces the notion that you really should lock down your scenarios before you start designing, and then hope to %DEITY% that the Important People don't change their minds half-way through ;-)&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=325109" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Tin Foil Hat Tool</title><link>http://blogs.msdn.com/ptorr/archive/2004/07/26/196594.aspx</link><pubDate>Mon, 26 Jul 2004 11:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:196594</guid><dc:creator>ptorr</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/196594.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=196594</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=196594</wfw:comment><description>
    &lt;div class="Section1"&gt;
      &lt;p&gt;
        &lt;span&gt;Based on some of &lt;a style="text-decoration:none;" href="http://weblogs.asp.net/ptorr/archive/2004/03/06/85266.aspx#194630"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;Nicole's feedback&lt;/span&gt;&lt;/a&gt;, I decided to write a basic app that checked your .NET security settings for you -- kind of like a very basic version of the Windows XP SP2 "Security Centre" tool which pops up and annoys you if you don't have the firewall or Automatic Updates turned on. (Whilst I disagree with Nicole's opinions on the role of CLR security, I do agree with her that we need to keep users more informed about the state of their machine).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Anyway, you can get the source for the app as &lt;a style="text-decoration:none;" href="http://weblogs.asp.net/ptorr/articles/CasHealthMonitor.aspx"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;a UUEncoded blob&lt;/span&gt;&lt;/a&gt; (I really need to organise some place to host binaries...). Copy the contents of that page (not including the menu, comments section, etc.) into a text file and save it with a &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;UUE&lt;/span&gt; extension. Then open the file with &lt;a style="text-decoration:none;" href="http://www.winzip.com/"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;WinZip&lt;/span&gt;&lt;/a&gt; or an archive utility of your choice and extract the contents somewhere on your machine.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Build the solution and copy the two output EXEs into the same folder. Then run &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;CasHealthMonitor.exe&lt;/span&gt; and behold its unrivalled suckiness. Play around with CAS and make some "dangerous" changes (eg, &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;caspol -en -cg 1 -levelfinal on&lt;/span&gt;) to see what happens (you'll have to wait a few seconds). Then immediately revert your changes (&lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;caspol -en -cg 1 -levelfinal off&lt;/span&gt;) to reduce the chances of your machine being hacked.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p class="Heading3-P" style="margin-top:12pt;margin-bottom:3pt;page-break-after:avoid;"&gt;
        &lt;span class="Heading3-H"&gt;Some notes:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;This application doesn't prove anything; all it does is show you coloured tin foil hat icons depending on what the CLR reports for the various security zones, but there are various ways to spoof this (see below)&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;I hate the way Notify Icons are implemented in the CLR. So many bugs / annoying behaviours&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;I really wish I could have a proper Balloon notification window (see previous point)&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;The app could be extended to use a config file mapping arbitrary evidence to arbitrary expected permissions (eg, you could map &lt;a style="text-decoration:none;" href="\\server\foo\bar"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;\\server\foo\bar&lt;/span&gt;&lt;/a&gt; to FullTrust and make sure it was doing OK)&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;Don't run this app on your production machines (all the usual disclaimers apply)&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;The code is ugly; I'm not a Windows Forms coding expert &lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;In fact, I'm not any kind of coding expert &lt;/span&gt;
      &lt;/p&gt;
      &lt;p class="Heading3-P" style="margin-top:12pt;margin-bottom:3pt;page-break-after:avoid;"&gt;
        &lt;span class="Heading3-H"&gt;How it works:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Every ten seconds or so, the app spawns a little helper process (&lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;casstate.exe&lt;/span&gt;) that spits out some basic security information to &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;stdout&lt;/span&gt; (it has to do this because policy is never reloaded by a process). This output is captured and parsed and the results are displayed in the tray icon / list view. The helper process checks a few things, but they aren't foolproof:&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;It checks if CAS is enabled, but a trojaned CLR install could lie about this state&lt;/span&gt;
      &lt;/p&gt;
      &lt;p style="margin-top:12pt;margin-left:36pt;text-indent:-18pt;"&gt;
        &lt;span&gt;
          &lt;span style="font-family:Symbol;font-style:normal;text-decoration:none;font-weight:normal;"&gt;·&lt;span style="padding-left:13.5pt;"&gt;&lt;/span&gt;&lt;/span&gt;It checks to see if each Zone is using the default permission set for that zone, but a badly / maliciously configured system could have changed the contents of the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Internet&lt;/span&gt; named permission set to be the same as &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FullTrust&lt;/span&gt; and this app would be none the wiser&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;Although I really don't think there's much value in this app, maybe you can learn a bit about resolving policy groups or something from it. Or, more likely, you can learn how &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; to program a system tray application in Windows Forms. &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;I wonder if Whidbey is any better...?&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=196594" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>RequestRefuse and RequestOptional example</title><link>http://blogs.msdn.com/ptorr/archive/2004/07/21/189538.aspx</link><pubDate>Wed, 21 Jul 2004 13:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:189538</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/189538.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=189538</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=189538</wfw:comment><description>
    &lt;div class="Section1"&gt;
      &lt;p&gt;
        &lt;span&gt;
          &lt;a style="text-decoration:none;" href="http://weblogs.asp.net/ptorr/archive/2004/07/01/170998.aspx#171864"&gt;
            &lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;Dave asks&lt;/span&gt;
          &lt;/a&gt; for an example of how to use &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;RequestRefuse&lt;/span&gt; and &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;RequestOtional&lt;/span&gt;. Here's my attempt to post a &lt;span style="font-style:italic;"&gt;short&lt;/span&gt; blog entry that describes it (luckily I had the code already at hand... ;-) ). &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;
          &lt;a style="text-decoration:none;" href="http://weblogs.asp.net/ptorr/articles/RequestDemoCode.aspx"&gt;
            &lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;The code&lt;/span&gt;
          &lt;/a&gt; consists of two libraries ("Optional" and "Refuse") and a main program for accessing them both. Basically just copy each bit of code into the right file, run &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;build.bat&lt;/span&gt; and then run &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;main.exe&lt;/span&gt;.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;The "Optional" file has the following declarations in it:&lt;/span&gt;
      &lt;/p&gt;
      &lt;div style="border-top:solid 1pt #99CCFF;padding-top:1pt;border-bottom:solid 1pt #99CCFF;padding-bottom:1pt;border-right:solid 1pt #99CCFF;padding-right:4pt;border-left:solid 1pt #99CCFF;padding-left:4pt"&gt;
        &lt;div style=""&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;// Let us show MessageBox windows&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;[&lt;/span&gt;assembly&lt;span style="color:#008080;"&gt;:&lt;/span&gt;UIPermission&lt;span style="color:#008080;"&gt;(&lt;/span&gt;SecurityAction&lt;span style="color:#008080;"&gt;.&lt;/span&gt;RequestMinimum&lt;span style="color:#008080;"&gt;,&lt;/span&gt; Window&lt;span style="color:#008080;"&gt;=&lt;/span&gt;UIPermissionWindow&lt;span style="color:#008080;"&gt;.&lt;/span&gt;SafeSubWindows&lt;span style="color:#008080;"&gt;)]&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;// Nothing else is required&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;[&lt;/span&gt;assembly&lt;span style="color:#008080;"&gt;:&lt;/span&gt;PermissionSet&lt;span style="color:#008080;"&gt;(&lt;/span&gt;SecurityAction&lt;span style="color:#008080;"&gt;.&lt;/span&gt;RequestOptional&lt;span style="color:#008080;"&gt;,&lt;/span&gt; Name&lt;span style="color:#008080;"&gt;=&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;"Execution"&lt;/span&gt;&lt;span style="color:#008080;"&gt;)]&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;span&gt;As you can see, it requests the ability to display "safe" windows (MessageBoxes and the like) and says that &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Execution&lt;/span&gt; is optional (and since &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;Execution&lt;/span&gt; is always granted by &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;RequestOptional&lt;/span&gt;, this basically means that nothing else is required).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;The "Refuse" file has the following declarations in it:&lt;/span&gt;
      &lt;/p&gt;
      &lt;div style="border-top:solid 1pt #99CCFF;padding-top:1pt;border-bottom:solid 1pt #99CCFF;padding-bottom:1pt;border-right:solid 1pt #99CCFF;padding-right:4pt;border-left:solid 1pt #99CCFF;padding-left:4pt"&gt;
        &lt;div style=""&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;// Let us show MessageBox windows&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;[&lt;/span&gt;assembly&lt;span style="color:#008080;"&gt;:&lt;/span&gt;UIPermission&lt;span style="color:#008080;"&gt;(&lt;/span&gt;SecurityAction&lt;span style="color:#008080;"&gt;.&lt;/span&gt;RequestMinimum&lt;span style="color:#008080;"&gt;, &lt;/span&gt;Window&lt;span style="color:#008080;"&gt;=&lt;/span&gt;UIPermissionWindow&lt;span style="color:#008080;"&gt;.&lt;/span&gt;SafeSubWindows&lt;span style="color:#008080;"&gt;)]&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008000;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008000;"&gt;// Refuse access to the Environment&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;[&lt;/span&gt;assembly&lt;span style="color:#008080;"&gt;:&lt;/span&gt;EnvironmentPermission&lt;span style="color:#008080;"&gt;(&lt;/span&gt;SecurityAction&lt;span style="color:#008080;"&gt;.&lt;/span&gt;RequestRefuse&lt;span style="color:#008080;"&gt;, &lt;/span&gt;Unrestricted&lt;span style="color:#008080;"&gt;=&lt;/span&gt;&lt;span style="color:#800000;"&gt;true&lt;/span&gt;&lt;span style="color:#008080;"&gt;)]&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;span&gt;As you can see, it requests the ability to display "safe" windows (MessageBoxes and the like) and says that it refuses to access the Environment, even if policy grants it that permission.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;The main program then simply tries to run a handful of (identical) methods on an object from each assembly, some of which will demand specific permissions:&lt;/span&gt;
      &lt;/p&gt;
      &lt;div style="border-top:solid 1pt #99CCFF;padding-top:1pt;border-bottom:solid 1pt #99CCFF;padding-bottom:1pt;border-right:solid 1pt #99CCFF;padding-right:4pt;border-left:solid 1pt #99CCFF;padding-left:4pt"&gt;
        &lt;div style=""&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;"\r\nBasic execution:"&lt;/span&gt;&lt;span style="color:#008080;"&gt;);&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;try&lt;/span&gt;
              &lt;span style="color:#008080;"&gt; { &lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;t&lt;span style="color:#008080;"&gt;.&lt;/span&gt;ReturnAString&lt;span style="color:#008080;"&gt;()); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;catch&lt;/span&gt;
              &lt;span style="color:#008080;"&gt;(&lt;/span&gt;Exception&lt;span style="color:#008080;"&gt; &lt;/span&gt;ex&lt;span style="color:#008080;"&gt;) { &lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;ex&lt;span style="color:#008080;"&gt;.&lt;/span&gt;Message&lt;span style="color:#008080;"&gt;); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;"\r\nMessageBox:"&lt;/span&gt;&lt;span style="color:#008080;"&gt;);&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;try&lt;/span&gt;
              &lt;span style="color:#008080;"&gt; { &lt;/span&gt;t&lt;span style="color:#008080;"&gt;.&lt;/span&gt;ShowMessageBox&lt;span style="color:#008080;"&gt;(); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;catch&lt;/span&gt;
              &lt;span style="color:#008080;"&gt;(&lt;/span&gt;Exception&lt;span style="color:#008080;"&gt; &lt;/span&gt;ex&lt;span style="color:#008080;"&gt;) { &lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;ex&lt;span style="color:#008080;"&gt;.&lt;/span&gt;Message&lt;span style="color:#008080;"&gt;); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;"\r\nEnvironment:"&lt;/span&gt;&lt;span style="color:#008080;"&gt;);&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;try&lt;/span&gt;
              &lt;span style="color:#008080;"&gt; { &lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;t&lt;span style="color:#008080;"&gt;.&lt;/span&gt;GetUsername&lt;span style="color:#008080;"&gt;()); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;catch&lt;/span&gt;
              &lt;span style="color:#008080;"&gt;(&lt;/span&gt;Exception&lt;span style="color:#008080;"&gt; &lt;/span&gt;ex&lt;span style="color:#008080;"&gt;) { &lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;ex&lt;span style="color:#008080;"&gt;.&lt;/span&gt;Message&lt;span style="color:#008080;"&gt;); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
            &lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;"\r\nFile IO:"&lt;/span&gt;&lt;span style="color:#008080;"&gt;);&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;try&lt;/span&gt;
              &lt;span style="color:#008080;"&gt; { &lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;t&lt;span style="color:#008080;"&gt;.&lt;/span&gt;ReadFile&lt;span style="color:#008080;"&gt;()); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
          &lt;p class="Code-P" style="margin-top:12pt;margin-top:0pt;"&gt;
            &lt;span&gt;
              &lt;span style="color:#008080;"&gt;
              &lt;/span&gt;
              &lt;span style="color:#008080;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
              &lt;span style="color:#800000;"&gt;catch&lt;/span&gt;
              &lt;span style="color:#008080;"&gt;(&lt;/span&gt;Exception&lt;span style="color:#008080;"&gt; &lt;/span&gt;ex&lt;span style="color:#008080;"&gt;) { &lt;/span&gt;Console&lt;span style="color:#008080;"&gt;.&lt;/span&gt;WriteLine&lt;span style="color:#008080;"&gt;(&lt;/span&gt;ex&lt;span style="color:#008080;"&gt;.&lt;/span&gt;Message&lt;span style="color:#008080;"&gt;); }&lt;/span&gt;&lt;/span&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;span&gt;If you have done everything successfully, you should see that code using &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;RequestOptional&lt;/span&gt; fails to run both the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;GetUserName&lt;/span&gt; method (which needs &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;EnvironmentPermission&lt;/span&gt;) and the &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;ReadFile&lt;/span&gt; method (which needs &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileIOPermission&lt;/span&gt;), whilst the code using &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;RequestRefuse&lt;/span&gt; only fails to run &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;GetUserName&lt;/span&gt; because it explicitly refused &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;EnvironmentPermission&lt;/span&gt; but was still granted &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;FileIOPermission&lt;/span&gt;.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;The "Optional" code is therefore less susceptible to luring attacks because it can't do anything except execute and show MessageBox windows (even by accident), whereas the "Refuse" code could theoretically be tricked into doing anything other than accessing environment variables (yes, this is a very convoluted example ;-) ).&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=189538" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Everett SP1 Tech Preview and VSA / VSTO</title><link>http://blogs.msdn.com/ptorr/archive/2004/07/18/186900.aspx</link><pubDate>Mon, 19 Jul 2004 02:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:186900</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/186900.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=186900</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=186900</wfw:comment><description>
    &lt;div class="Section1"&gt;
      &lt;p&gt;
        &lt;span&gt;
          &lt;span style="font-weight:bold;"&gt;
          &lt;/span&gt;
          &lt;span class="Heading3Char-H"&gt;Updated information about VSTO below&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;As you may know, the .NET Framework 1.1 ("Everett") Service Pack 1 Tech Preview is &lt;a style="text-decoration:none;" href="http://msdn.microsoft.com/netframework/downloads/updates/sptechpreview/default.aspx"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;available for download&lt;/span&gt;&lt;/a&gt;. You should try to install this on your &lt;span style="font-weight:bold;font-style:italic;"&gt;non-production machines&lt;/span&gt; and test to make sure your existing applications continue to run. Please report any problems you find to the &lt;a style="text-decoration:none;" href="http://communities.microsoft.com/newsgroups/default.asp?icp=techpreview&amp;amp;slcid=us"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;.NET Framework Tech Preview newsgroups&lt;/span&gt;&lt;/a&gt;.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;
          &lt;span style="font-weight:bold;"&gt;
          &lt;/span&gt;
          &lt;span style="font-weight:bold;"&gt;Just a quick word of warning though:&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;I wasted about 5 hours the other night tracking down a "bug" in a brain-dead simple VSA host app I had built. Turns out that whilst the JScript engine works flawlessly (of course :-) ), the VB VSA engine doesn't work in the Tech Preview. Basically any attempt to call &lt;span class="InlineCode-H" style="font-family:Lucida Console;"&gt;IVsaEngine.Run&lt;/span&gt; will result in a "The parameter is incorrect" error due to a communication problem between the native and managed code portions. It will apparently be fixed for RTM.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;
          &lt;span style="font-weight:bold;"&gt;
          &lt;/span&gt;
          &lt;span style="font-weight:bold;"&gt;Update Monday 19th July:&lt;/span&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;It turns out that VSTO 2003 is also affected by this same problem, but in a different way. VSTO customisations will run OK with the Tech Preview, but they may not get unloaded when you close the associated Word or Excel document. This means that if you hook application-level events, or you run code off a timer, or perform some other actions that can get triggered by things outside the scope of the document, your code may continue to run and receive these notifications even when the original file is closed. Closing down the host application will of course unload the code correctly.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;This message brought to you by the number '4' and the letters 'F' and 'S.' You figure it out ;-)&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=186900" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category></item><item><title>Developing as Non-Admin</title><link>http://blogs.msdn.com/ptorr/archive/2004/03/21/93352.aspx</link><pubDate>Sun, 21 Mar 2004 07:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:93352</guid><dc:creator>ptorr</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/93352.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=93352</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=93352</wfw:comment><description>&lt;DIV class=Section1&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;A href="http://www.develop.com/kbrown/"&gt;Keith Brown&lt;/A&gt; writes &lt;A href="http://weblogs.asp.net/ptorr/archive/2003/09/21/56188.aspx#93319"&gt;a comment&lt;/A&gt; in one of my older posts about a chapter in his book dealing with &lt;A href="http://www.develop.com/kbrown/book/html/lifestyle.html"&gt;developing code as a non-Admin&lt;/A&gt;. A great read if you're still one of those people running as an Administrator because you think you need to in order to do programming. Maybe you should buy the book if he ever gets the link working :-) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;One addition: you &lt;SPAN style="FONT-WEIGHT: bold"&gt;can&lt;/SPAN&gt; run Windows Explorer (and the related control panel applets) from your Admin account as long as you've set the "Run Explorer windows in a separate process" option &lt;SPAN style="FONT-STYLE: italic"&gt;from the admin account&lt;/SPAN&gt;. Run &lt;SPAN style="FONT-FAMILY: Lucida Console"&gt;regedit&lt;/SPAN&gt; from your Admin console, navigate to:&lt;/SPAN&gt; &lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;SPAN style="FONT-FAMILY: Lucida Console"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Lucida Console"&gt;&lt;FONT color=#000080&gt;HKEY_CURRENT_USER\ Software\ Microsoft\ Windows\ CurrentVersion\ Explorer\ Advanced&lt;/FONT&gt;&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;and set the &lt;SPAN style="FONT-FAMILY: Lucida Console"&gt;&lt;FONT color=#000080&gt;SeparateProcess&lt;/FONT&gt;&lt;/SPAN&gt; DWORD to 0x01.&lt;/SPAN&gt; &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=93352" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Developers frustrated by Administrators</title><link>http://blogs.msdn.com/ptorr/archive/2003/12/06/56372.aspx</link><pubDate>Sun, 07 Dec 2003 00:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56372</guid><dc:creator>ptorr</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56372.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56372</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56372</wfw:comment><description>&lt;div class="Section1"&gt;
      &lt;p class="Normal-P" style="margin-top:12pt;"&gt;
        &lt;span class="Normal-H"&gt;A link on &lt;a href="http://www.slashdot.org/"&gt;Slashdot&lt;/a&gt; points to a &lt;a href="http://www.softwarereality.com/lifecycle/role_fragmentation.jsp"&gt;rant&lt;/a&gt; about why one developer thinks that administrators are the scum of the earth. There are some good counter arguments on the &lt;a href="http://developers.slashdot.org/comments.pl?sid=88327&amp;amp;cid=0&amp;amp;pid=0&amp;amp;startat=&amp;amp;threshold=5&amp;amp;mode=nested&amp;amp;commentsort=0&amp;amp;op=Change"&gt;comments&lt;/a&gt; page. &lt;/span&gt;
      &lt;/p&gt;
      &lt;p class="Normal-P" style="margin-top:12pt;"&gt;
        &lt;span class="Normal-H"&gt;It's interesting because we spend quite a bit of time at work trying to make sure that the products we design for &lt;span style="font-weight:bold;"&gt;developers&lt;/span&gt; will actually be sanctioned by &lt;span style="font-weight:bold;"&gt;administrators&lt;/span&gt;. There's no point in building &lt;a href="http://msdn.microsoft.com/vstudio/"&gt;the world's best enterprise development tool&lt;/a&gt; if nobody is allowed to install it.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p class="Normal-P" style="margin-top:12pt;"&gt;
        &lt;span class="Normal-H"&gt;Getting most developer scenarios to work as a &lt;a href="http://msdn.microsoft.com/library/en-us/dv_vstechart/html/tchDevelopingSoftwareInVisualStudioNETWithNon-AdministrativePrivileges.asp"&gt;normal user in Visual Studio&lt;/a&gt; is one aspect of this ongoing effort. &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56372" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Randomness/default.aspx">Randomness</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>VSTO Security Model</title><link>http://blogs.msdn.com/ptorr/archive/2003/11/03/56304.aspx</link><pubDate>Tue, 04 Nov 2003 00:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56304</guid><dc:creator>ptorr</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56304.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56304</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56304</wfw:comment><description>
&lt;p&gt;I somehow (?) came across a &lt;a
href="http://www.luckypines.com/blog/archives.aspx?month=2003-10#fe00f31f-fef9-48b2-bac3-870e5dd7df1b"&gt;blog&lt;/a&gt;
where a customer wonders how VSTO tightens up security. That's an interesting
story. &lt;/p&gt;
&lt;p&gt;As many of you will know, Office already has a security
model for VBA and COM Add-Ins that is based on two types of evidence (digital
signatures and &amp;quot;installed&amp;quot; code) and a fairly simple run / prompt /
don't run policy system. You can read more about these security levels in one
of &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_dsvba.asp"&gt;Siew
Moi's articles&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The CLR also has a very rich, extensible security model
based around evidence, permissions and policy. You can read more about it on
MSDN, or perhaps look at &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/msdnmag/issues/02/09/securityinnet/toc.asp"&gt;Don
Box's article&lt;/a&gt; (which I haven't actually read... it just turned up in a
search result and I trust him to write good stuff ;-) ).&lt;/p&gt;
&lt;p&gt;Anyway, when it came to defining the model for VSTO we knew
we didn't want to invent a 3rd way of doing it, so we had to choose whether to
use the Office model or the CLR model. Now in hindsight it may seem obvious to
some readers that the .NET model was the only way to go, but we were very
concerned about confusing existing Office developers with the new model and
having them just turn off security altogether to &amp;quot;make it work,&amp;quot; so
we looked quite hard at integrating with the Office model. Nevertheless it had
to be implemented on the CLR policy system, and whilst this was perfectly
doable (did I mention the system is very flexible?) it would have been abusing
the system somewhat...&lt;/p&gt;
&lt;p&gt;So anyway, what we thought about was basically the following
(you could even use this for a blueprint of your own model, if you really need
to proxy trust decisions from a legacy system to .NET...):&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;1)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;Borrow
from the digital signatures evidence that Office uses&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;2)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;Honour
only the &amp;quot;High&amp;quot; mode (must be signed to run; never prompt for
elevated privileges)&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;3)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;Use
the Office trusted publishers list&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;4)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;Build
our own &lt;b&gt;TrustedOfficeMacro&lt;/b&gt;
membership condition and evidence objects&lt;/p&gt;
&lt;p&gt;Basically how it would work would be that we'd get a request
to load an assembly and check if it had an AuthentiCode signature that was
generated by a certificate in the Office Trusted Publishers list. If so, we'd
load the macro with the &lt;b&gt;TrustedOfficeMacro&lt;/b&gt;
evidence (essentially &amp;quot;vouching&amp;quot; for the goodness of it). Otherwise,
we wouldn't load it. We'd also rely on you having a rule in your .NET policy
that granted FullTrust to things loaded with &lt;b&gt;TrustedOfficeMacro&lt;/b&gt; evidence. Another thing we could have done (and
probably would have done eventually, although it's not in the original spec)
was that if the assembly was &amp;quot;installed&amp;quot; (in the Templates directory)
and&lt;b&gt; &lt;/b&gt;the user had the &amp;quot;Trust
installed templates and add-ins&amp;quot; feature checked, we'd load the assembly
with &lt;b&gt;TrustedOfficeMacro&lt;/b&gt; evidence.&lt;/p&gt;
&lt;p&gt;[Aside: When presenting this to people, many of them
initially said &amp;quot;hey, that's a security hole -- anyone can claim to be
loading &lt;b&gt;TrustedOfficeMacro&lt;/b&gt;-s and get
arbitrary code to run!&amp;quot; But of course in order to present evidence to the
CLR, you have to be fully trusted yourself (or so close as it makes no
difference) so if you could load arbitrary code with bogus &lt;b&gt;TrustedOfficeMacro&lt;/b&gt; evidence, not only could you also load it with
bogus Microsoft Strongname evidence, you could also just go ahead and do
whatever bad stuff you wanted to do by yourself. The point being that whenever
you're thinking about security problems, think about the preconditions required
to execute the attack and move on if it's already &amp;quot;game over&amp;quot;
(defence in depth techniques not withstanding... :-) )]&lt;/p&gt;
&lt;p&gt;This kind of seems cool because if you have a lot invested
in VBA or COM AddIn solutions, and you already have a code signing certificate
that's trusted on all your machines, you could just move to .NET code and still
have it run on all your users' machines without any configuration changes.
Unfortunately it had some limitations, not least of which was that it didn't
mesh at all with all the new .NET stuff, so if you wanted to write both
WinForms and Office code you'd have two security stories to play with instead
of just one, even if you never wrote a line of VBA in your life. Also handing
out evidence at assembly load time is something you want to avoid if possible,
since in general you will not be in control of subsequent assembly loads in the
same domain (eg if the assembly links to a second assembly, then that assembly
will automatically be loaded by the CLR as needed, and you don't get any say as
to what evidence it should have).&lt;/p&gt;
&lt;p&gt;So we decided 100% .NET was the way to go, but as I thought
I'd mentioned before (but I can't find a link), we thought that the default
.NET logic of &amp;quot;if it's on the local machine, you obviously installed it,
and if you installed it you obviously trust it, so it should get
FullTrust&amp;quot; didn't really work for Office documents, so we had to do
something about it.&lt;/p&gt;
&lt;p&gt;[This blog is already longer than I thought it would be, and
I haven't even started to answer the question yet! Such is the way of the
blogger]&lt;/p&gt;
&lt;p&gt;The problem was how to get Office documents to ignore the
default Machine-level rule that granted FullTrust to MyComputerZone, but left
policy as-is for all other applications. Some ideas that floated (and were
immediately shot down :-) ) were to simply modify Machine policy when you
installed Office to lock down your machine, or to somehow cleverly modify
policy just before you launched Office and then put it back again as soon as it
had been cached in the app. But of course the first one would have broken every
locally-installed app from here to next Tuesday, and the latter was a complete
hack that was just not going to happen. Oh and you need to be an admin to mess
with non-User policy, and normal users had to be able to run (and even develop!)
VSTO documents.&lt;/p&gt;
&lt;p&gt;It was clear we couldn't mess with persistent policy, but
luckily the CLR folks were very clever and had the foresight to include &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconsettingapplicationdomainlevelsecuritypolicy.asp"&gt;AppDomain-level
policy&lt;/a&gt; that let AppDomain hosts (like Office) tinker with policy to their
hearts' desire. So there were some initial (again, very short-lived) plans to
simply slap a static &amp;quot;MyComputerZone : Nothing&amp;quot; rule into AppDomain
policy and be done with it. Great! No code would run from MyComputer.
Unfortunately, this was an absolute statement -- no code would ever run from
MyComputer - &lt;b&gt;EVER&lt;/b&gt;! Because .NET
policy is intersected between levels (Enterprise, Machine, User, AppDomain),
even if someone had added a rule at Machine or Enterprise level to say
&amp;quot;Code signed with ACME certificate : FullTrust&amp;quot;, we'd blow that away
with our more restrictive &amp;quot;Nothing&amp;quot; rule at the AppDomain level. &lt;/p&gt;
&lt;p&gt;Back to the drawing board.&lt;/p&gt;
&lt;p&gt;We had to honour any and all changes that users might have
made to their policy, at any level, with arbitrary degrees of complexity. And
not only did we have to preserve the rules themselves (ACME gets FullTrust), we
had to preserve the hierarchy of rules as well (trusting ACME in the Intranet
Zone is very different to trusting them in &lt;b&gt;all
&lt;/b&gt;Zones!). The only things we would throw away would be &amp;quot;implicit&amp;quot;
or &amp;quot;generic&amp;quot; rules based on Zones (MyComputer, Internet, etc) and
AllCode (which matches everything in existence). And herein lies the beauty /
simplicity / wackiness of it all. &lt;/p&gt;
&lt;p&gt;We copy all the code groups from all the other policy levels
into the AppDomain, and kill off the ones we don't like.&lt;/p&gt;
&lt;p&gt;So let's say you have a &amp;quot;typical&amp;quot; machine at ACME
corp, with the following policy (simplified to only mention the MyComputer and
LocalIntranet Zones):&lt;/p&gt;
&lt;p&gt;&lt;st1:place w:st="on"&gt;&lt;st1:City w:st="on"&gt;&lt;b&gt;Enterprise&lt;/b&gt;&lt;/st1:City&gt;&lt;/st1:place&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;AllCode : FullTrust&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Machine&lt;br&gt;
&lt;/b&gt;&amp;nbsp;&amp;nbsp;AllCode : Nothing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyComputerZone : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ECMA Strongname : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Microsoft Strongname : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ACME Corp Publisher : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LocalIntranetZone : LocalIntranet&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://coolserver/"&gt;http://coolserver/&lt;/a&gt;
: LocalIntranet&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ACME Corp Publisher : FullTrust&lt;/p&gt;
&lt;p&gt;&lt;b&gt;User&lt;br&gt;
&lt;/b&gt;&amp;nbsp;&amp;nbsp;AllCode : FullTrust&lt;/p&gt;
&lt;p&gt;This is basically the out-of-the-box policy, with some
additional rules to allow code signed by ACME Corp to run off the &lt;a
href="http://coolserver/"&gt;http://coolserver/&lt;/a&gt; machine and on the local
machine. We then create an AppDomain policy that is the concatenation of those
three levels, so it looks like this:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;AppDomain&lt;br&gt;
&lt;/b&gt;&amp;nbsp;&amp;nbsp;AllCode : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;AllCode : Nothing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyComputerZone : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ECMA Strongname : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Microsoft Strongname : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ACME Corp Publisher : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LocalIntranetZone : LocalIntranet&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://coolserver/"&gt;http://coolserver/&lt;/a&gt;
: LocalIntranet&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ACME Corp Publisher : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;AllCode : FullTrust&lt;/p&gt;
&lt;p&gt;It looks funny because AllCode appears three times and can't
make up its mind about whether to grant FullTrust or Nothing, but we don't
worry about that. All the granted permissions at this level will eventually be
union-ed together, so we can duplicate as many things as we want as randomly as
we want. &lt;/p&gt;
&lt;p&gt;Finally we &amp;quot;clean&amp;quot; out the AllCode and Zone groups
so it looks like this (changes in &lt;b&gt;bold&lt;/b&gt;;
we'll have colour one day, &lt;a
href="http://blogs.gotdotnet.com/robmen/commentview.aspx/73e48d62-4e7a-4f74-86ad-86e8077d175e"&gt;I
promise&lt;/a&gt;!):&lt;/p&gt;
&lt;p&gt;&lt;b&gt;AppDomain&lt;br&gt;
&lt;/b&gt;&amp;nbsp;&amp;nbsp;AllCode : &lt;b&gt;Nothing&lt;/b&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;AllCode : Nothing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyComputerZone : &lt;b&gt;Nothing&lt;/b&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ECMA Strongname : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Microsoft Strongname : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ACME Corp Publisher : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LocalIntranetZone : &lt;b&gt;Nothing&lt;/b&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://coolserver/"&gt;http://coolserver/&lt;/a&gt;
: LocalIntranet&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ACME Corp Publisher : FullTrust&lt;br&gt;
&amp;nbsp;&amp;nbsp;AllCode : &lt;b&gt;Nothing&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Now we have preserved 100% the semantics of the user's
&amp;quot;explicit&amp;quot; policy changes (trusting URLs, publishers, sites, etc.)
but we've thrown away the &amp;quot;implicit&amp;quot; default policy of giving
FullTrust to the local machine. Because of the way policy resolution works, the
AppDomain level can never grant more permissions to code than would otherwise
have been granted (it can only take them away), although at first blush it
sometimes seems that the AppDomain policy can &amp;quot;leak&amp;quot; permissions,
especially when you have a &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconattributesofcodegroups.asp"&gt;LevelFinal
codegroup&lt;/a&gt;. But it all comes out in the wash.&lt;/p&gt;
&lt;p&gt;To this day people still say to me &amp;quot;I don't know how
this system works, and it looks really crazy, but it seems to do the job.&amp;quot;
And it does (at least I hope it does!). I spent most of the last 18 months or
so worrying about this (along with many other things :-) ) and it's been
through a bunch of testing and modelling and &amp;quot;desk checks&amp;quot; manually
walking through the algorithm. Hopefully no-one finds any holes with it!&lt;/p&gt;
&lt;p&gt;A final note on the development experience. The strict
policy we made for Office documents was meant to protect end-users against
accidentally running malicious software, so it made sense to lock everything
down by default. But of course the developers building those applications
probably do want to be able to run them, and in general they won't have access
to (or won't want to use) code signing and won't want to mess with policy too
much (because it's hard to get right, and they'd likely turn off security
altogether to make their stuff work, which is a &lt;b&gt;bad&lt;/b&gt; idea). So we needed a different story for developers.&lt;/p&gt;
&lt;p&gt;We went round and round on possible solutions for this one
for most of the product cycle. There were three main possibilities:&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;1)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;A
machine configuration setting (regkey) to disable our policy&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;2)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;Runtime
checks between Office and VS to disable our policy&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;3)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;Design
time changes to policy to grant permissions to code&lt;/p&gt;
&lt;p&gt;The first one sucked because it meant that a dev machine was
wide open to attack. Just because the developer was doing VS development with
Office and wanted to run their own code, that didn't mean we should leave their
machine open to attack from malicious code. Devs sometimes open bad attachments
too, you know ;-)&lt;/p&gt;
&lt;p&gt;The second one was an improvement because it would only
disable the policy if Office detected that a debugger was attached, and that
the document being opened matched the one inside the debugger. This was cool
because it meant that the dev machine was no longer wide open -- policy would
be enforced for all documents except the ones the developer was actively
debugging -- but it had another drawback. It worked if the developer hit F5 in
VS (Run with Debugging), but would fail if the developer hit Ctrl+F5 (Run
without Debugging) or if they ran their code from Explorer.&lt;/p&gt;
&lt;p&gt;The third one (which we shipped with) ensured that
developers could always run the code they built themselves, because we'd update
their user-level policy to trust the output location of the VS project. This
meant that you were still protected from random malicious code (unless you
happened to save over the top of one of your own previously-trusted projects!)
and it didn't rely on having the VS debugger attached. The main drawbacks were
that it didn't work out-of-the-box if you developed on a network share (you
can't trust network shares by modifying user-level policy unless an admin has
already updated machine policy), it didn't work if you moved your solution
after building it, and you could end up with hundreds of entries in policy over
time as you built more and more solutions. &amp;lt;sigh&amp;gt; oh well, you can't have
everything.&lt;/p&gt;
&lt;p&gt;So there you have it. Many people think that the stuff that comes
out of &lt;st1:City w:st="on"&gt;&lt;st1:place w:st="on"&gt;Redmond&lt;/st1:place&gt;&lt;/st1:City&gt;
is just rubbish with no real thought behind it and with the only purpose being
to make as much money as possible as quickly as possible and with no real
concern for the user. Hopefully you'll see from my blog (and everyone else's)
that this isn't the case. We think long and hard about all the features we
ship, and we often have to trade off several different design ideas based on
conflicting requirements, changing priorities, tight schedules, etc.&lt;/p&gt;
&lt;p&gt;I'm the first person to admit that the VSTO policy is very
draconian and, quite frankly, a pain in the neck for a lot of developers who
just want their code to work. But I'll also be the first (and loudest) person
to defend that design as being the only &amp;quot;right&amp;quot; choice for where we are
today. (And if Siew Moi wasn't on vacation, I'm sure she'd be second in line
:-) ).&lt;/p&gt;
&lt;p&gt;Thoughts?&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56304" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>PDC Session on Office Development with VS "Whidbey"</title><link>http://blogs.msdn.com/ptorr/archive/2003/10/23/56303.aspx</link><pubDate>Thu, 23 Oct 2003 09:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56303</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56303.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56303</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56303</wfw:comment><description>
&lt;p&gt;If you're going to the &lt;a
href="http://mymsevents.com/MyMSEvents/"&gt;PDC in LA&lt;/a&gt; this year and you're
interested in Office development, you should add &lt;a
href="http://mymsevents.com/MyMSEvents/search.aspx?s=1&amp;amp;keywords=&amp;amp;keywordtype=3&amp;amp;track=103&amp;amp;speaker=43888&amp;amp;timeslot=0&amp;amp;future=0&amp;amp;submit=Search+Now%21"&gt;Reza
Chitsaz's session&lt;/a&gt; to your calendar (TLS346). He has some great content and
some really cool demos showing the new stuff that will be coming out in the
future. And we only just released &lt;a
href="http://msdn.microsoft.com/vstudio/office/"&gt;VSTO 1.0&lt;/a&gt; the other day! &amp;lt;g&amp;gt;&lt;/p&gt;
&lt;span&gt;Mention
this blog at the session and you'll receive a free... um... well nothing
really. I don't have anything to give you. Sorry.&lt;/span&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56303" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Mitigating Code Repurposing Attacks</title><link>http://blogs.msdn.com/ptorr/archive/2003/10/21/56296.aspx</link><pubDate>Wed, 22 Oct 2003 01:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56296</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56296.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56296</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56296</wfw:comment><description>
&lt;p&gt;&lt;span&gt;As I mentioned in a &lt;a
href="http://blogs.gotdotnet.com/ptorr/PermaLink.aspx/5eded8da-11f4-4b9c-adbb-e175c52bfd10"&gt;previous
blog&lt;/a&gt;, there are some pretty creative (and destructive) things people can do
with your code if you're not careful. Just as a kitchen knife can be used to
cut cheese or to kill someone, so your code can be used to increase
productivity or wreak digital havoc.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It's not all bad news
though. There are several things you can do to help mitigate attacks based on
code repurposing, although unfortunately there is no panacea and many of these
techniques will not be applicable to all given scenarios. A much shorter
article that mentions some key mitigating factors can be found in the &lt;a
href="http://msdn.microsoft.com/library/en-us/dv_wrcore/html/wrconSpecificSecurityConsiderations.asp?frame=true"&gt;VSTO
documentation online&lt;/a&gt;. But if you've got a spare chunk of time, by all means
read on.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thanks to &lt;a
href="http://www.icc1.org.uk/pages/Winter%20Blossom.htm"&gt;Siew Moi&lt;/a&gt;, Mike
Howard, and the Office security folks for giving this a once-over before
posting :-)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Root Cause&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;The root cause of
repurposing comes from &lt;b&gt;trusting input
data&lt;/b&gt;. Michael Howard has a lot to say about this in Chapter 10 of &lt;a
href="http://www.microsoft.com/mspress/books/5957.asp"&gt;Writing Secure Code 2nd
Edition&lt;/a&gt; (aptly titled &lt;b&gt;All Input is
Evil&lt;/b&gt;), but in repurposing attacks it's not just your code that is trusting
potentially bad data, it's the end-user, too!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;With a typical
web-based application, checking your inputs isn't so hard since you mostly need
to worry about things like form fields, query strings, and HTTP headers. (You
may also need to worry about any external systems you connect to, such as a
database, if that figures into your threat model). In most cases, you can
assume that the server your application is being hosted on is trustworthy,
along with any other data on it such as configuration files, web page content,
and so on.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The problem with
Office-based development is that your code is hosted inside a very dynamic,
very mobile container (the document), and in general you cannot assume that &lt;b&gt;any &lt;/b&gt;part of that document's content is
trustworthy.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Not the warning text
you put in &lt;b&gt;BIG BOLD WARNING TEXT&lt;/b&gt; at
the top of the document.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Not the names or
positions of the controls on the document.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Not the hidden
worksheets where you store database connection strings.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Not the
configuration settings you put inside a hidden region with white text on a
white background in 1 point WingDings font.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Nothing.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So our goal is to do
one or more -- always think of &amp;quot;defence in depth&amp;quot; --&lt;span&gt;Â  &lt;/span&gt;of the following things:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol start=1 type=1&gt;
 &lt;li&gt;&lt;span&gt;Eliminate our dependence on information
     inside the document&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
 &lt;li&gt;&lt;span&gt;Ensure that the information in the
     document is trustworthy&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
 &lt;li&gt;&lt;span&gt;Check that the information inside the
     document falls within a &amp;quot;reasonable&amp;quot; range&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
 &lt;li&gt;&lt;span&gt;Provide cues to the user about the
     purpose of the code they are running&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
 &lt;li&gt;&lt;span&gt;Elicit explicit user consent before
     performing potentially harmful actions&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
 &lt;li&gt;&lt;span&gt;Probably some more things here!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span&gt;So let's look at
these in turn.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Eliminate dependence on untrustworthy information&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;In my previous blog,
I used the example of a &amp;quot;Format my Drive&amp;quot; document that contained
instructions for formatting your hard drive, along with &lt;b&gt;Yes&lt;/b&gt; and &lt;b&gt;No&lt;/b&gt; buttons that
invoked the appropriate code. In this sample, the &lt;b&gt;code&lt;/b&gt; doesn't make any decisions based on inputs (it has none), but
the &lt;b&gt;user&lt;/b&gt; does. The code assumes that
the user will always be presented with adequate contextual information (eg,
&amp;quot;clicking this button will format your drive!&amp;quot;), but this is not the
case. The user has no idea that there is &lt;b&gt;no
link&lt;/b&gt; between the text surrounding the buttons and the actions the buttons
take; they think if the text says &amp;quot;Download unlimited free MP3s now!&amp;quot;
then that's what the button will do. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Oops!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So even in this
case, the code implicitly trusts its &amp;quot;inputs&amp;quot; (the user invoking the
code) and it should not be. Something as dangerous as a &amp;quot;Format my
Drive&amp;quot; control should provide additional feedback to the user about the
actions they are about to perform, as noted in one of the next sections of this
blog.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It's also a good
idea to think about the things you &lt;b&gt;can&lt;/b&gt;
depend on. Resources on the local machine, such as files or registry keys,
should in general be trustworthy (see note below!). So should other servers
that your code communicates with, as long as they are under your control. And
of course you can trust your own code not to have been tampered with, as long
as it is signed or living in a secure location. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;NOTE&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: I said above that you can trust the local machine. This assumes we
are trying to mitigate against repurposing attacks where one user sends a
malformed document to another user in an attempt to get them to &lt;b&gt;do something harmful to themselves&lt;/b&gt;. You
&lt;b&gt;cannot&lt;/b&gt; trust resources on the client
computer in other scenarios, such as when you are building a server-side
solution, because then a hostile client could be used to subvert your security
system. Servers need to protect themselves from malicious clients, and clients
need to protect themselves from malicious servers. Different scenarios call for
different threat models and different mitigation strategies.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So if your solution
needs to persist data such as user preferences or other snippets of information
that you come to rely on, you can write it to the registry or to a config file
(not in %&lt;b&gt;ProgramFiles%&lt;/b&gt;, but in &lt;b&gt;%UserProfile%&lt;/b&gt;) or use some other
mechanism to persist it. Just don't persist it in the document, because then
you'll never be able to read it out again without worrying about the contents.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Contacting servers
is a bit trickier. You might want to contact, say, a trusted web service on &lt;a
href="http://myserver/"&gt;http://myserver/&lt;/a&gt; to download information, but if
you hard-code that URL into your solution then you will have trouble when you
need to move the service to another machine. The obvious answer is to stick the
URL of the server inside the document... but you can't do that because it's not
trustworthy! This is where you could do something like an Active Directory
lookup to figure out which server to contact. I've been told it's possible, but
I'm not an AD expert so you'll have to figure that one out on your own ;-).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Ensure the information is trustworthy&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Let's say you
absolutely have to rely on the information inside the document, for whatever
reason. Now you have to make sure the content in the document is as trustworthy
as your code itself, which means severely limiting what can be done with the
document.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Two properties of
code that makes it &amp;quot;easy&amp;quot; to secure in the CLR are that:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;i)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;You can
sign the code, which can be used to detect any modifications made to it&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;ii)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;You can
keep it in a fixed location, which can be used to ensure nobody can modify /
overwrite it&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Unfortunately,
neither of these two properties apply to documents in the general sense. The
whole point of having document-based solutions is so that you can modify them
(thereby making signatures pretty useless) and that you can send them around to
people, copy them to your hard drive, and so on (thereby making location pretty
useless). Nevertheless, depending on the scenario you may be able to do one of
these things in your solutions.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Signing a document
in Office 2003 is pretty easy -- go to &lt;b&gt;Tools&lt;/b&gt;
-&amp;gt; &lt;b&gt;Options&lt;/b&gt; -&amp;gt; &lt;b&gt;Security&lt;/b&gt; and click on the &lt;b&gt;Digital Signatures&lt;/b&gt; button, where you
can select one of your certificates and add your signature to the document.
Once the document is signed, no-one can tamper with it in any way without
breaking the signature, but as I mentioned in my &lt;a
href="http://blogs.gotdotnet.com/ptorr/commentview.aspx/d644c676-dac5-46ef-96c6-140fdfa6bcce"&gt;Old
Fashioned Security blog&lt;/a&gt;, there's a big problem with signing content:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul type=disc&gt;
 &lt;li&gt;&lt;span&gt;Unless the recipient expects the
     document to be signed (and knows how to verify it), it doesn't really help
     you. An attacker will just remove the signature altogether and go on their
     wicked way&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;So either you have
to educate all your users about how to inspect digital signatures, or you can
do something about it yourself.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;In Word, you can use
the object model inside your code to check if the active document contains a
signature, and if so if it is from the right person (ie, you) and if it is
valid. Inside your startup code, you can do something similar to the following
to ensure that your code is running inside a genuine document that you created
(if &lt;a href="http://blogs.gotdotnet.com/robmen/"&gt;Rob&lt;/a&gt; had finished the
WordML to HTML transform by now, this would be in glorious &lt;a
href="http://www.widescreenmuseum.com/oldcolor/technicolor1.htm"&gt;Technicolor&lt;/a&gt;,
but alas he hasn't so it's not):&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt;
ThisDocument_Open() &lt;span&gt;Handles&lt;/span&gt; ThisDocument.Open&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; signature &lt;span&gt;As&lt;/span&gt; Office.Signature&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; foundSignature &lt;span&gt;As&lt;/span&gt; &lt;span&gt;Boolean&lt;/span&gt; = &lt;span&gt;False&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt;
(ThisDocument.Signatures.Count &amp;lt; 1) &lt;span&gt;Then&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&amp;quot;This document
is not signed.&amp;quot;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Take
appropriate action here...&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisDocument.Close()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;If&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;For&lt;/span&gt; &lt;span&gt;Each&lt;/span&gt; signature &lt;span&gt;In&lt;/span&gt;
ThisDocument.Signatures&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Bail out early
on invalid signatures&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt;
((signature.IsValid = &lt;span&gt;False&lt;/span&gt;) &lt;span&gt;Or _&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(signature.IsCertificateRevoked
= &lt;span&gt;True&lt;/span&gt;)) &lt;span&gt;Then&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&amp;quot;This
document's signature is bad.&amp;quot;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisDocument.Close()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;If&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Add the
appropriate strings here&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt;
((signature.Signer = &amp;quot;ACME Corp&amp;quot;) &lt;span&gt;And _&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(signature.Issuer =
&amp;quot;Verisign&amp;quot;)) &lt;span&gt;Then&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;'
You could also check the sign date if you want&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&amp;quot;This
document is signed correctly.&amp;quot;)&lt;span&gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foundSignature = &lt;span&gt;True&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Exit&lt;/span&gt;
&lt;span&gt;For&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;If&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Next&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt;
(foundSignature = &lt;span&gt;False&lt;/span&gt;) &lt;span&gt;Then&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&amp;quot;This
document's signature is missing.&amp;quot;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Take
appropriate action here...&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisDocument.Close()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;If&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;There's a bit of a
chicken-and-egg problem here for both VBA and VSTO developers here, but for
different reasons. With VBA, because the code is included in the document's
signature you have to sign the document &lt;b&gt;after&lt;/b&gt;
you have written and tested your code. This could require you to build, test,
and re-sign your document many times, or it could require you to have some kind
of mode where the document ignores invalid signatures while in development
(remember, this &lt;b&gt;cannot&lt;/b&gt; be a flag
stored in the document itself, but it could be a registry key you use to
disable signature checking on your dev box). With VSTO, the assembly is built
and signed independently from the document, but since the custom properties
which link to the assembly form part of the signature, it is not possible to
move the assembly after the document is signed, so that must be done as the
final step before officially releasing the document.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This
&amp;quot;problem&amp;quot; of having the code (or the link to the code) be part of the
signature actually helps us prevent some attacks as well. Imagine, as outlined
in my previous blog, that you have a Budget document and an HR document. Both documents
are signed, and both assemblies are signed, but by some horribly bad
coincidence, it's possible to point the HR document at the Budget code (or
vice-versa) and do some damage to the document recipient. This will not work,
since swapping out the code (or the link to the code) will break the signature.
The only real attack possible here is if you can take over the URL at which the
linked code lives, in which case you could replace the HR assembly with the
Budget assembly. So you need to make sure your servers are protected from
having unauthorised people uploading content!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;One potential
problem here is that the &lt;b&gt;Signature&lt;/b&gt;
object in Word only tells you the name of the signer and the authority that
issues that certificate, but not the rest of the trust chain up to the root
authority. It is possible (but unlikely) to have two signatures, both created
by &amp;quot;Bob Smith&amp;quot; and issued by &amp;quot;ACME Corp Authority&amp;quot;, but for
them to be two different Bob Smiths issued from two different ACME Corp Authorities.
(Thankfully you still have to trust the root authority, so it's not as if any
old hacker could create such a hierarchy in order to fool your code, but it's
something to keep in mind). Siew Moi has written a &lt;a
href="http://msdn.microsoft.com/library/en-us/dnword2k2/html/odc_wdds.asp?frame=true"&gt;great
article on Word signatures&lt;/a&gt;, and it includes a download that has some more
code to play with.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Unfortunately, there
is no programmatic support for checking digital signatures in Excel, so you
cannot use this technique. Also, you may not have the money to buy a
certificate from &lt;a href="http://verisign.com/"&gt;Verisign&lt;/a&gt; or &lt;a
href="http://www.thawte.com/"&gt;Thawte&lt;/a&gt; or one of the other big vendors, and
you may not have your own PKI servers with which to issue your own
certificates. In this case, you can &amp;quot;tie&amp;quot; your document to a specific
location, such as a trusted (and read-only) share on a server, or to a specific
&amp;quot;install&amp;quot; location on the user's machine. (This is similar to how the
&lt;a
href="http://msdn.microsoft.com/downloads/samples/internet/default.asp?url=/downloads/samples/internet/components/SiteLock/default.asp"&gt;SiteLock&lt;/a&gt;
feature works for ActiveX controls). At startup, you can check that the
document's location is where it is supposed to be, and take appropriate actions
(such as closing the document) if the document comes from a suspicious
location. This has the problem of baking URLs or other locations into your
code, which means it's impossible to ever move the solution if you need to, so
you may want to use a Registry key or Active Directory property or some other
external (but still trusted) mechanism to figure out if the document is hosted
in a secure location:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt;
ThisDocument_Open() &lt;span&gt;Handles&lt;/span&gt; ThisDocument.Open&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt; (ThisDocument.FullName
&amp;lt;&amp;gt; _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;\\appserver\secure\myapp.doc&amp;quot;) &lt;span&gt;Then&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&amp;quot;This document
is not secure&amp;quot;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;ThisDocument.Close()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;If&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Obviously if you
require your document to be signed, that means the user can never actually
modify it and then save it. And if you require it to be in a specific location,
that means the user can't put it on their desktop or mail it to a friend.
That's kind of a problem for most documents, since they are designed to be
modified and saved and moved around. (I show a slightly less draconian version
of this in the next section).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;One way around this
is to have your &amp;quot;document&amp;quot; act like a mini application hosted inside
Word or Excel, and have it load and save its own &amp;quot;documents&amp;quot;. This is
made super-easy by the XML support in Word and Excel 2003, where you can import
or export the XML content of a document to a separate file without actually
saving all the markup and other stuff that makes up your
&amp;quot;application&amp;quot;. As long as your solution lends itself well to having only
the data saved and loaded into your static template, you should be good to go
-- just provide your own &amp;quot;Open&amp;quot; and &amp;quot;Save&amp;quot; mechanisms
inside your document that load and save XML files that are pumped right into
the mapped XML structure of your document. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Here's some sample
code for doing it in Excel -- Word is harder since you can't automatically
import XML into a Word document; you need to load the DOM yourself and insert
text into each node of the document. For this simple solution, you can create a
spreadsheet with pretty formatting, etc. and then do the following:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;1)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;Map an
XML Schema into the document (a really basic one follows if you need it)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;2)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;Add a
single Command Button from the &lt;b&gt;Controls
Toolbox&lt;/b&gt; toolbar. Open the Properties window for it and give it a name of &lt;b&gt;cmdLoad&lt;/b&gt;. Delete the &lt;b&gt;Caption&lt;/b&gt; so it is blank.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;3)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;(Optional)
Digitally sign the document with a certificate to prove that you can do this
without modifying the content&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here's a simple schema you can map to a spreadsheet. Save it
with an extension of &lt;b&gt;.XSD&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;lt;?&lt;/span&gt;&lt;span&gt;xml&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;encoding&lt;/span&gt;&lt;span&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&amp;gt;&lt;br&gt;
&amp;lt;&lt;/span&gt;&lt;span&gt;xs:schema&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;=&amp;quot;simple&amp;quot;&lt;/span&gt;&lt;span&gt;&lt;br&gt;
&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;targetNamespace&lt;/span&gt;&lt;span&gt;=&amp;quot;http://tempuri.org/simple.xsd&amp;quot;&lt;/span&gt;&lt;span&gt;&lt;br&gt;
&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;elementFormDefault&lt;/span&gt;&lt;span&gt;=&amp;quot;qualified&amp;quot;&lt;br&gt;
&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;xmlns&lt;/span&gt;&lt;span&gt;=&amp;quot;http://tempuri.org/simple.xsd&amp;quot;&lt;/span&gt;&lt;span&gt;&lt;br&gt;
&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;xmlns&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;mstns&lt;/span&gt;&lt;span&gt;=&amp;quot;http://tempuri.org/simple.xsd&amp;quot;&lt;br&gt;
&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;xmlns&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;xs&lt;/span&gt;&lt;span&gt;=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;xs:element&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&amp;quot;SimpleTest&amp;quot;&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;xs:complexType&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;xs:sequence&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;xs:element&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&amp;quot;FirstName&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;=&amp;quot;xs:string&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;xs:element&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&amp;quot;LastName&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;=&amp;quot;xs:string&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;xs:sequence&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;xs:complexType&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;xs:element&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;br&gt;
&amp;lt;/&lt;/span&gt;&lt;span&gt;xs:schema&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And here's the code you can use - just dump it into the default codespit
of a VSTO solution, nuking the original &lt;b&gt;ThisWorkbook_Open&lt;/b&gt;
handler:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;WithEvents&lt;/span&gt;
cmdLoad &lt;span&gt;As&lt;/span&gt; MSForms.CommandButton&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;' Called when the workbook is opened.&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt; ThisWorkbook_Open() &lt;span&gt;Handles&lt;/span&gt;
ThisWorkbook.Open&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;InitialiseUI()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt; InitialiseUI()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdLoad = FindControl(&amp;quot;cmdLoad&amp;quot;)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt; (cmdLoad &lt;span&gt;Is&lt;/span&gt; &lt;span&gt;Nothing&lt;/span&gt;) &lt;span&gt;Then&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox(&amp;quot;Document is
corrupt!&amp;quot;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;If&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdLoad.Caption = &amp;quot;Load XML&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdLoad.AutoSize = &lt;span&gt;True&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt; cmdLoad_Click() &lt;span&gt;Handles&lt;/span&gt;
cmdLoad.Click&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LoadXml()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt; LoadXml()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Gather the filename through
a custom dialog, etc.&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; filename &lt;span&gt;As&lt;/span&gt; &lt;span&gt;String&lt;/span&gt; =
&amp;quot;C:\temp\export.xml&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisWorkbook.XmlMaps(1).Import(filename)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Don't prompt user to save&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisWorkbook.Saved = &lt;span&gt;True&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt; SaveXml()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Gather the filename through
a custom dialog, etc.&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; filename &lt;span&gt;As&lt;/span&gt; &lt;span&gt;String&lt;/span&gt; =
&amp;quot;C:\temp\export.xml&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisWorkbook.XmlMaps(1).Export(filename, &lt;span&gt;True&lt;/span&gt;)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;' Don't prompt user to save&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisWorkbook.Saved = &lt;span&gt;True&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;' Handle the Save event to just
save the data&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt; ThisWorkbook_BeforeSave( _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;ByVal&lt;/span&gt; SaveAsUI &lt;span&gt;As&lt;/span&gt; &lt;span&gt;Boolean&lt;/span&gt;, &lt;span&gt;ByRef&lt;/span&gt; Cancel &lt;span&gt;As&lt;/span&gt; &lt;span&gt;Boolean&lt;/span&gt;) _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Handles&lt;/span&gt;
ThisWorkbook.BeforeSave&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SaveXml()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Cancel = &lt;span&gt;False&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Another way to
ensure that the information in the document is trustworthy without resorting to
signatures or site-locking your document is to ensure that you create it all
yourself, from within your code, and that you make it easily understandable by
the user. For example, if you have a button on a Word document that will format
the hard drive when it is clicked, don't just give the button a caption of &lt;b&gt;Yes&lt;/b&gt; and rely on the surrounding text to
explain what it does. A more descriptive caption, such as &lt;st1:Street w:st="on"&gt;&lt;st1:address
 w:st="on"&gt;&lt;b&gt;Format Drive&lt;/b&gt;&lt;/st1:address&gt;&lt;/st1:Street&gt;&lt;b&gt; C:&lt;/b&gt; will be much better. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;And don't just set
the &lt;b&gt;Caption&lt;/b&gt; of the button using the
property grid in Word or Excel, since that value can be changed by the attacker
and is not stored as part of your VBA or .NET assembly. Even if your code is
signed, the attacker can change that property and not invalidate the signature
(it &lt;b&gt;will&lt;/b&gt; invalidate the signature of
the document, if it has one, but it &lt;b&gt;won't&lt;/b&gt;
invalidate the signature of the code). Instead, you should explicitly set the
caption of your button during your initialisation code, so that it always says
what you want it to say. This is what I did above in the sample Excel code.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Don't rely on
automatically generating warning text into the document though (eg, injecting
&amp;quot;&lt;b&gt;This will format your drive!&lt;/b&gt;&amp;quot;
in big red letters at the start of the document), since no matter what you do
the bad guys will probably figure out a way of obscuring it (hiding the region,
placing a white bitmap over the top of the text, etc.).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you need more UI
than you can get by putting captions on your buttons, then you need to
implement some kind of form (see below) or &amp;lt;gasp&amp;gt; build an ActiveX
control where you can display all your information in a reliable manner. If you
don't have to have your control hosted directly on the document surface, a
SmartDocument solution offers a really good alternative because the attacker
has no way to influence what appears in the Task Pane. You can be sure that any
warning text or other UI you place in the Task Pane will be there when the user
runs the solution.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Another way to avoid
&amp;quot;untrustworthy&amp;quot; callers in VBA is to make your methods &lt;b&gt;Private&lt;/b&gt; (VSTO does not have this
problem since there is no way through the Office UI to invoke managed code). If
you are placing controls on the document surface, make sure you use ActiveX
controls (from the &amp;quot;Control Toolbox&amp;quot; toolbar), not Forms controls
(from the &amp;quot;Forms&amp;quot; toolbar). Adding an event handler to an ActiveX
control creates a private method that cannot be invoked by any means other than
firing the event on the named control, whereas the macros you assign to Forms
controls are just public subroutines that can be hooked up to any old event
source. Also, since Forms controls aren't programmable, you can't
programmatically change their content (as described above). &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you are building &lt;b&gt;CommandBars&lt;/b&gt; or menu items, don't use
the Office UI to hookup event handlers, since again they must be public and
hence repurposable (swap the &amp;quot;Save&amp;quot; event handler for the
&amp;quot;Delete&amp;quot; one...). Instead you should build up the &lt;b&gt;CommandBar&lt;/b&gt; programmatically (so you can
set the text and images on each control as outlined above) and declare all your
controls inside your solution &lt;b&gt;WithEvents&lt;/b&gt;
so you can handle the events with a private handler, not a public sub. There is
some sample code for VSTO in &lt;a
href="http://msdn.microsoft.com/library/en-us/odc_vsto2003_ta/html/odc_VSTCommBar.asp?frame=true"&gt;this
article&lt;/a&gt;, and the sample solutions that ship with the product also show how
to create menus and toolbars. Some sample VBA code is below:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;WithEvents&lt;/span&gt;
cmdSave &lt;span&gt;As&lt;/span&gt; CommandBarButton&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;WithEvents&lt;/span&gt;
cmdDelete &lt;span&gt;As&lt;/span&gt; CommandBarButton&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;Private&lt;/span&gt; &lt;span&gt;Sub&lt;/span&gt;
Document_Open()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CreateCommandBar&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;End Sub&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;Private Sub&lt;/span&gt; CreateCommandBar()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; bar As CommandBar&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; i As Integer&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; oldContext As
Object&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;On Error GoTo Handler&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Delete any existing instances of the bar&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Must loop backwards since we're deleting items&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;For&lt;/span&gt; i = CommandBars.Count
&lt;span&gt;To&lt;/span&gt; 1 &lt;span&gt;Step&lt;/span&gt; -1&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set bar = CommandBars(i)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt;
((bar.BuiltIn = False) And _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(bar.Name = &amp;quot;My
Bar&amp;quot;)) &lt;span&gt;Then&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bar.Delete&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;End If&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Next&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Create our own temporary bar&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Set&lt;/span&gt; bar =
CommandBars.Add(&amp;quot;My Bar&amp;quot;, , , True)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bar.Visible = True&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Add new buttons&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Set&lt;/span&gt; cmdSave =
bar.Controls.Add(msoControlButton)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdSave.Caption = &amp;quot;Save&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdSave.Style = msoButtonCaption&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Set&lt;/span&gt; cmdDelete =
bar.Controls.Add(msoControlButton)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdDelete.Caption = &amp;quot;Delete&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdDelete.Style = msoButtonCaption&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Exit the sub&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Return&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;Handler:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox &amp;quot;CommandBar not created:&amp;quot; &amp;amp; _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vbNewLine &amp;amp; _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Err.Description, _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vbOKOnly Or vbInformation,
&amp;quot;Error&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;End Sub&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;Private Sub&lt;/span&gt; cmdSave_Click( _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ByVal Ctrl As Office.CommandBarButton, _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CancelDefault As Boolean)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox &amp;quot;Save clicked!&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;End Sub&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;Private Sub&lt;/span&gt; cmdDelete_Click( _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ByVal Ctrl As Office.CommandBarButton, _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CancelDefault As Boolean)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox &amp;quot;Delete Clicked!&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;End Sub&lt;/span&gt;&lt;br&gt;
&lt;![if !supportLineBreakNewLine]&gt;&lt;br&gt;
&lt;![endif]&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Check the information for &amp;quot;reasonableness&amp;quot;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Sometimes you really
do need to rely on the information in the document. In WordBlogX, for example,
I persist &lt;b&gt;all &lt;/b&gt;the information about
a blog entry (content, unique ID, creation date, etc) into a document, and then
next time you load that document I suck it all back out again. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;Oh No!&lt;/span&gt;&lt;/b&gt;&lt;span&gt; &lt;b&gt;I'm breaking all my own rules!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Well, here's where you need to take a step back and consider
how the data is used (what's the worst thing that could happen?) and what kinds
of reasonable limits you can place on the data inside the document. For
example, if you have a budget spreadsheet that accepts a value for the current
year's maximum budget, it probably shouldn't be negative and it probably
shouldn't be more than &lt;a href="http://www.imdb.com/title/tt0118655/"&gt;ONE
MILLION DOLLARS&lt;/a&gt; (or whatever is appropriate for your organisation). If
there's simply no valid reason for such values, you should check for them and
reject them -- building correct, robust software gets you half way to building
secure software. &lt;/p&gt;
&lt;p&gt;Same goes for (eg) embedded URLs -- if you have to embed a URL
in the document, but it should only be one of 3 known servers, make sure it
really is one of those servers. One common mistake in web programming is to use
a &lt;b&gt;&amp;lt;select&amp;gt;&lt;/b&gt; object to provide
the user with a &amp;quot;fixed&amp;quot; list of options in the browser, and then to
blindly accept whatever value the client returns in the server code. This is
broken because users can send ANY values to your web server; they're not limited
to the options shown by the browser UI. Office applications are no different
(depending on the scenarios) -- just because you provide the user the
convenience of 3 or 4 different options, it doesn't mean they can't inject
their own.&lt;/p&gt;
&lt;p&gt;Do you store dates in the document? Does it make sense to have
a date outside of a relatively small range, such as today +/- a month? If not,
then check for it and throw away the bad values. Are you expecting a range of
10 cells in Excel? Then don't just &amp;quot;loop until done&amp;quot; -- explicitly
check for the 10 cells and if there are more or less then take some defensive
action. Unfortunately in these cases developers (including Microsoft
developers) often try and &amp;quot;help&amp;quot; the user by trying really hard to
work-around all the errors the user makes, inferring things from partial
information, and so on. But whilst this can help users in some situations, it
usually comes back around to bite you when an attacker figures out how to fool
your oh-so-smart algorithms into doing something unexpected.&lt;/p&gt;
&lt;p&gt;In the case of WordBlogX, there's no real validation I can do
on the document content (it's just arbitrary text) but I do check that the GUID
is in a valid format and that the persisted date and time values are in a valid
format. I could do extra work to check the GUID against some trusted store (eg,
the Registry) but that complicates the solution and then I'd have a bunch of
essentially useless GUIDs hanging around. Even if &lt;span&gt;&lt;a href="http://blogs.gotdotnet.com/robmen/"&gt;Rob&lt;/a&gt;&lt;/span&gt; gets the &lt;a
href="http://blogs.gotdotnet.com/robmen/CategoryView.aspx/wordblogx"&gt;WordBlogX
setup working&lt;/a&gt;, he could in theory delete the registry data when the program
was uninstalled, but since it's probably considered &amp;quot;user data&amp;quot; &lt;a
href="http://blogs.gotdotnet.com/robmen/PermaLink.aspx/47e3be27-79c9-40f6-a1ca-ee4240a7ea76"&gt;we
couldn't even do that&lt;/a&gt;. So the registry keys would live forever, and it
would be impossible to move documents from one machine to another without also
moving the regkeys. I should probably make sure that the Modified date is on or
after the Created date, and that neither of them are in the future or the
distant past.&lt;/p&gt;
&lt;p&gt;I take the approach that I can be quite lax with WordBlogX in
this instance because it's not protecting anything too valuable, other than my
credentials to the web server. About the worst thing someone could do (other
than steal my login) would be to send me a document with the GUID and creation
date of an existing entry, and fool me into &amp;quot;updating&amp;quot; (ie,
clobbering) the old content instead of creating a new entry. Or they could put
some nasty text in the &lt;b&gt;Description&lt;/b&gt;
field and hide it, hoping I won't see it. Neither of those are likely to happen
since I don't accept blog entries from anyone else, and even if I did there's a
confirmation step before posting where I would get to double-check the content.
But your solutions will have different threat models and thus require different
levels of attention.&lt;/p&gt;
&lt;p&gt;Regular expressions are a really cool way of validating input,
and Michael has some things to say about them in his book &amp;lt;plug
notagain=&amp;quot;oh yes&amp;quot;&amp;gt;&lt;a
href="http://www.microsoft.com/mspress/books/5957.asp"&gt;Writing Secure Code&lt;/a&gt;&amp;lt;/plug&amp;gt;.
You can weed out all kinds of nasty things using a few expressions, and that
will help you stop not only security bugs, but general code quality issues,
too.&lt;/p&gt;
&lt;p&gt;One other really cool thing that you get for &amp;quot;free&amp;quot;
with VSTO is that &lt;a
href="http://blogs.gotdotnet.com/ptorr/commentview.aspx/9f6e31e8-937e-4328-b457-132360cd51ed"&gt;the
document itself is subject to security checks&lt;/a&gt;. I don't worry too much about
WordBlogX because it's simply not possible under a default security policy for
someone to send me an e-mail attachment that links to the code, or for someone
to point me to a web site that opens a document and links to the code. Unless
the document is copied to my local machine, it cannot access any assemblies,
even if they are trusted. &lt;/p&gt;
&lt;p&gt;Unfortunately VBA does not provide this degree of protection,
but you could attempt to mimic it by parsing the document's location during
your startup routines to see if the URL is in an expected location or not. This
is a slightly different approach from locking the document to a very specific
location as mentioned above (which lets you &amp;quot;guarantee&amp;quot; that the
content is trustworthy). Instead this enables you to flag &amp;quot;suspect&amp;quot;
uses of the document (eg, hosted off external web sites) while still enabling
users some degree of freedom about where they save the files.&lt;/p&gt;
&lt;p&gt;Rather than looking for &amp;quot;http:&amp;quot; at the start of the
string (or some other &amp;quot;black list&amp;quot; approach), you should use a
&amp;quot;white list&amp;quot; approach where you know the &amp;quot;good&amp;quot; locations
and look explicitly for them. Why should you do this? Well, for one thing, if
the attacker learns what &amp;quot;bad&amp;quot; patterns you are looking for, they'll
just pick a new pattern that isn't caught by your code. There's only a small,
finite number of &amp;quot;good&amp;quot; locations that the average document should be
in, but there are an infinite number of &amp;quot;bad&amp;quot; ones and you can't
check for them all. Also if you just do the naive thing and check for a
protocol like &lt;b&gt;http://&lt;/b&gt; you'll get
confused by the Temporary Internet Files folder and treat things that really
came from the web as if they came from the local machine (bad bad bad!)&lt;/p&gt;
&lt;p&gt;As an example, if budget spreadsheets should only ever be
stored in the &lt;b&gt;Budgets&lt;/b&gt; folder, then
you should make sure that the path to the document begins with that text. Of
course this means that the code won't work outside of an e-mail attachment, but
maybe that's not such a bad thing.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;'
Note this is VBA, not VB .NET :-)&lt;br&gt;
&amp;nbsp;&amp;nbsp;' Makes sure the file is in the right folder&lt;br&gt;
&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;Sub&lt;/span&gt; CheckDocumentFolder()&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; path As &lt;span&gt;String&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Dim&lt;/span&gt; expectedPath As &lt;span&gt;String&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expectedPath = Application.DefaultFilePath &amp;amp; _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;\Budgets\&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path = ThisWorkbook.path&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;If&lt;/span&gt; (InStr(path,
expectedPath) &amp;lt;&amp;gt; 1) &lt;span&gt;Then&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox &amp;quot;This is a Budget document. It
should be &amp;quot; &amp;amp; _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;stored in the 'Budgets'
folder.&amp;quot;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThisWorkbook.Close&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;If&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span&gt;End&lt;/span&gt; &lt;span&gt;Sub&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;NOTE: &lt;/b&gt;If it were
possible to call &lt;a
href="http://msdn.microsoft.com/workshop/security/szone/reference/ifaces/iinternetsecuritymanager/mapurltozone.asp?frame=true"&gt;MapUrlToZone&lt;/a&gt;
from VBA I'd also recommend you do that, because you should never really attempt
canonicalisation or parsing yourself, as outlined in &amp;lt;plug shouldgetkickback=&amp;quot;true&amp;quot;&amp;gt;&lt;a
href="http://www.microsoft.com/mspress/books/5957.asp"&gt;Writing Secure Code&lt;/a&gt;&amp;lt;/plug&amp;gt;,
chapter 11. Nevertheless, using a white list is better than nothing. If someone
knows of a way to get &lt;b&gt;MapUrlToZone&lt;/b&gt;
to work from VBA, that would be really cool info to share!&lt;/p&gt;
&lt;h3&gt;Provide cues to the user&lt;/h3&gt;
&lt;p&gt;A strategy that you can use to help alert the user of
impending doom is to provide them with some (subtle) cues that they are using
your application and not some innocuous document. Returning to the mis-matched
Budget vs. HR spreadsheet scenario, if the HR code displayed some kind of a
splash-screen upon loading then a user who believed they were opening a Budget
spreadsheet would become suspicious and presumably shutdown the document and contact
their administrator. &lt;/p&gt;
&lt;p&gt;Of course relying on a splash-screen alone is not a good idea,
since the user may never see it depending on how they are interacting with the
computer. It's just something else you can throw out there to make it even
harder for people to accidentally shoot themselves in the foot.&lt;/p&gt;
&lt;p&gt;If you have other forms of non-spoofable UI, they would be
good places to post some warning messages or other cues as to the purpose of
your application, but as I mentioned above this is hard to do unless you are
building a SmartDocument or you have a custom ActiveX control which you
completely own. &lt;/p&gt;
&lt;p&gt;If you show a form or some other UI as part of your solution,
ensure that the user can garner enough context from the information you show to
make good decisions, even in the face of malformed document content. Returning
to our favourite &amp;quot;format hard drive example&amp;quot;, let's say there was a
confirmation dialog that popped up (see next section) asking the user if they
wanted to continue or not. If the message box simply asks &amp;quot;Continue? [Yes]
[No]&amp;quot; then the user has no context other than what is presented in the
document itself, which could be anything at all (especially if you didn't use
the other strategies, such as using descriptive captions and initialising them
through code at load time). So make sure you give the user enough information
to make an informed choice, but don't overload them too much such that their
eyes glaze over and they learn to ignore your warnings.&lt;/p&gt;
&lt;h3&gt;Get consent from the user&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;You've done everything
you can to help prevent your code from being repurposed, but at the end of the
day you have to send some sensitive information to a URL stored in the document
or perform some other kind of operation that you're not entirely comfortable
with. &lt;a href="http://www.imdb.com/title/tt0111257/"&gt;Whaddayoudo?&lt;/a&gt; (Yes that
link will get old eventually).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Well, it's probably
not a bad idea to ask the user. Try not to ask them in a really obscure,
technical manner -- unless your user base is technical, of course -- but in
plain English (or the language of your choice :-)). Describe the badness that
could happen if this code were being used incorrectly, taking into account the
other mitigations you have employed. Speak in general terms if the specifics
are too technical, but don't over-simplify the gravity of the situation. Having
professional staff on hand to help with error messages, confirmation messages,
and other UI text is very helpful.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This section is really
quite general and doesn't apply only to code repurposing mitigation; it's just
good application design. If users are empowered to make informed choices,
they're more likely to make good choices. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;One of my pet peeves
in this area is people who use &lt;b&gt;MessageBox&lt;/b&gt;
calls with the &amp;quot;[OK] [Cancel]&amp;quot; buttons, but then they ask a Yes / No
question. Or even worse, they ask an ambiguous question, or put more than one
decision point in the dialog, or use double negatives. What's up with that?! I
can partially forgive it in DHTML programming, where &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/confirm.asp"&gt;window.confirm&lt;/a&gt;
only allows for OK and Cancel, but even there all you need to do is re-phrase
the prompt so it makes sense. I guess that in many cases they're just trying to
side-step the need to build their own dialog and try to hack their requirements
into MessageBox, when really they should just crack open the forms designer and
do their users a favour.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Users are generally
confused enough about computers and security already; you don't need to make it
worse by asking silly things like &amp;quot;Do you want to upload data or rollback
the transaction? &lt;/span&gt;[OK]&lt;span&gt;
[Cancel]&amp;quot;. Picking a bad default button is also a sign of poor design; you
should generally pick the &amp;quot;safe&amp;quot; default (usually &lt;b&gt;No&lt;/b&gt;, &lt;b&gt;Abort&lt;/b&gt;, or &lt;b&gt;Cancel&lt;/b&gt;) so
that if the user blindly hits &lt;b&gt;&amp;lt;Enter&amp;gt;&lt;/b&gt;
they aren't toast. And don't skimp on the &lt;b&gt;Cancel&lt;/b&gt;
button either, if it makes sense to cancel the entire operation in addition to
assenting or dissenting to a particular question. You can set the buttons, the
icon, and the default button for both &lt;a
href="http://msdn.microsoft.com/library/en-us/vbenlr98/html/vafctMsgBox.asp?frame=true"&gt;MsgBox
in VBA&lt;/a&gt; and &lt;a
href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWindowsFormsMessageBoxClassShowTopic9.asp?frame=true"&gt;MesssageBox.Show
in .NET&lt;/a&gt;, so there's no excuse for not doing it.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Finally, be consistent
with the way you word dialogs -- don't have one prompt saying:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul type=disc&gt;
 &lt;li&gt;&lt;span&gt;&amp;quot;Would
     you like to save changes before closing? [Yes] [No] [Cancel]&amp;quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;and another one
asking:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul type=disc&gt;
 &lt;li&gt;&lt;span&gt;&amp;quot;Would
     you like to close without saving? [Yes] [No] [Cancel]&amp;quot;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;Don't laugh, I've seen
applications like this.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Closing thoughts&lt;/h3&gt;
&lt;p&gt;It's not easy to build complex solutions that are both
easy-to-use and hard-to-repurpose, especially when you factor in user ignorance
or error. But as I mentioned earlier, it's a trade-off you have to make based
on the types of threats you think your solution might come up against, and the
consequences of someone successfully executing one of those threats. &lt;/p&gt;
&lt;p&gt;If you're writing a macro that bolds the active paragraph in
Word, you probably don't have much to worry about. It's kind of hard to make it
bold anything other than the active paragraph, and even if you could get it to
do that, what's the damage? Nothing that can't be fixed with an &lt;b&gt;Alt+Backspace&lt;/b&gt; (that's the old-fashioned
equivalent to &lt;b&gt;Ctrl+Z&lt;/b&gt;, for those who
don't know). &lt;/p&gt;
&lt;p&gt;But if you're building a spreadsheet for managing
multi-million-dollar portfolio accounts, or you deal with sensitive material
like HR records or legal contracts, you'd better be thinking of security. &lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56296" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Code Repurposing</title><link>http://blogs.msdn.com/ptorr/archive/2003/10/16/56270.aspx</link><pubDate>Thu, 16 Oct 2003 11:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56270</guid><dc:creator>ptorr</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56270.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56270</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56270</wfw:comment><description>
&lt;p&gt;&lt;span&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: I've now posted a &lt;a
href="http://blogs.gotdotnet.com/ptorr/commentview.aspx/4304d0d3-ac52-41f6-8137-aac3d380f8cd"&gt;follow
up entry&lt;/a&gt; to this blog that talks about some strategies you can use to
mitigate the kinds of problems outlined in this blog entry]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;lt;sigh&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Code repurposing really blows.
And it sucks. It sucks and it blows. And not necessarily in that order!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This blog could be short, or it
could be long. It depends on how much I ramble and how many side-topics I need
to bring in to talk about this most heinous of concepts. Hope you can stay
along for the ride.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So what is code re-purposing? I
talked about it a bit in a &lt;a
href="http://blogs.gotdotnet.com/ptorr/commentview.aspx/9f6e31e8-937e-4328-b457-132360cd51ed"&gt;previous
blog&lt;/a&gt;, but I'm just going to brain-dump again so please forgive me if I
repeat myself. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Myself.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;But before I start, I want to
talk a bit about the difference between &lt;b&gt;dangerous&lt;/b&gt;
code and &lt;b&gt;malicious&lt;/b&gt; code. Eric
touched on this subject in his blog &lt;a
href="http://blogs.gotdotnet.com/ericli/commentview.aspx/8dbf5993-77a1-4718-b562-7a8339a770d7"&gt;a
while ago&lt;/a&gt;, but in case you didn't read it or in case you're still not sure,
I'll start with a bit of a story. I'm doing this is so I can talk about the
difference between installing bad code, and having good code get repurposed
(something that a lot of really smart people don't understand).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: Word just crashed so I have to re-type this paragraph... argh!]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If I told you that the other
day I discovered some code on my machine that could erase all the files on my
computer and any network shares I have access to, you might be a bit alarmed.
If I told you that I also found some code that could send e-mails to all the
people in my Outlook contacts, you might start getting nervous. If &lt;a
href="http://blogs.gotdotnet.com/ptorr/commentview.aspx/4fc434fe-9295-496e-a528-9042b8f577bd"&gt;Mr.
Paranoid&lt;/a&gt; can't even keep his machine virus-free, then how can the rest of
the world? Run to the hills!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Well... someone just jumped to
a conclusion :-). I never said I had a virus; I said I had software that could
delete files (it's called the &lt;st1:place w:st="on"&gt;&lt;st1:State w:st="on"&gt;&lt;b&gt;DEL&lt;/b&gt;&lt;/st1:State&gt;&lt;/st1:place&gt; command),
and I said I had software that could send e-mail (it's called &lt;b&gt;Outlook&lt;/b&gt;). The &lt;st1:State w:st="on"&gt;&lt;st1:place
 w:st="on"&gt;&lt;b&gt;DEL&lt;/b&gt;&lt;/st1:place&gt;&lt;/st1:State&gt;
command is pretty dangerous -- it deletes data! -- but its operation is well
documented and only trusted entities can use it to delete files. It's not
malicious. Same for all recent versions of Outlook -- it can send mail, but
only when I want it to.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Installing vs Repurposing&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;At work when we're talking
about security problems, we often invoke a mythical &lt;b&gt;ACTIVEX&lt;/b&gt; &lt;b&gt;CONTROL OF ULTIMATE DESTRUCTION&lt;/b&gt;,
a control that will proceed to format the user's hard drive as soon as it is
initialised.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This control is talked about in
two different contexts:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;1)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;The &lt;b&gt;ACOUD&lt;/b&gt; is not installed on my machine,
but I visit a web site or open a document that attempts to download the control
for malicious purposes&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;2)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;The &lt;b&gt;ACOUD&lt;/b&gt; is installed on my machine and I
visit a web site or open a document that attempts to invoke the control for
malicious purposes&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;There is a significant
difference between these two scenarios, although quite often I have to expend
large amounts of time and effort trying to explain this difference to people to
show why they do (or do not) have a security problem with their designs.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;In the first case, we assume
that the control is 100% pure evil and has been developed by a hax0r. The
purpose of the control is to be downloaded to your machine and do as much
damage as possible as quickly as possible. When you visit the web page, the
browser attempts to download the control, and one of three things can happen:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;i.&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;The control is
blocked by your security settings&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;ii.&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;You are prompted
to download the control&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;iii.&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;span&gt;The control
installs without prompts&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The first one is most likely to
occur if the code is unsigned -- it's the default behaviour of IE -- and it's A
Good Thing. It will also happen if you browse the net in &amp;quot;High&amp;quot;
security mode, or if you are not running as an Administrator. In this case you
are safe from the ACOUD because it will never be installed and hence it can
never do its dirty work.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The second one is likely to
occur if the control is signed (remember, &lt;a
href="http://securityresponse.symantec.com/avcenter/venc/data/friendgreetings.html"&gt;the
bad guys can get certificates, too&lt;/a&gt;!) or if you have lowered your security
settings to allow unsigned controls to be downloaded with a prompt (not a good
idea!). In this case, you are prompted for your permission / consent to
download and install the control. If the browser can determine any interesting
security properties about the control (ie, its signature) then it will show you
this information; otherwise it will just kind of shrug its shoulders and go
&amp;quot;eh?&amp;quot; at you. Now if you decide to install and run the ACOUD, &lt;b&gt;then&lt;/b&gt; &lt;b&gt;it's your own fault&lt;/b&gt;! Yes, that's right! You and you alone are
responsible for deciding whether or not to install code on your computer. If
you make a bad trust decision (trusting unsigned code, or code from an
untrustworthy publisher, or code from someone you've never heard of like
&amp;quot;Permissioned Media&amp;quot;) then there's nothing Windows (or any other OS,
for that matter) can do to protect you.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Aside: It's quite funny in a
sad kind of way how all the &lt;a href="http://www.slashdot.org/"&gt;ABMers&lt;/a&gt; (&lt;b&gt;A&lt;/b&gt;nything &lt;b&gt;B&lt;/b&gt;ut &lt;b&gt;M&lt;/b&gt;icrosoft) think
that the point of Palladium (aka &lt;b&gt;NGSC&lt;/b&gt;,
&lt;b&gt;&lt;a
href="http://www.microsoft.com/resources/ngscb/default.mspx"&gt;N&lt;span&gt;ext &lt;/span&gt;G&lt;span&gt;eneration
&lt;/span&gt;S&lt;span&gt;ecure &lt;/span&gt;C&lt;span&gt;omputing &lt;/span&gt;B&lt;span&gt;ase&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;)
is to &lt;b&gt;control what software people
install on their machines&lt;/b&gt;. They think it's some nefarious plot to stop them
installing &lt;a href="http://www.kernel.org/"&gt;Linux&lt;/a&gt; or &lt;a
href="http://www.mozilla.org/"&gt;Mozilla&lt;/a&gt; or &lt;a
href="http://www.openoffice.org/"&gt;OpenOffice.org&lt;/a&gt; or whatever on their PCs.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: Oh dear, he just provided links to competitors' sites.
He'll probably get fired tomorrow!!!]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Boy would I sleep well at
night if I knew people couldn't install bad software on their PCs. No more
viruses or buggy user-written code to worry about! Of course I'd also be out of
a job, because a PC is useless if you can't install arbitrary code on it. Of
course the public just likes to talk about the OS, a browser, and a
productivity suite (usually in the context of &lt;a
href="http://www.microsoft.com/windows/default.mspx"&gt;Windows&lt;/a&gt; / &lt;a
href="http://www.microsoft.com/windows/ie/default.asp"&gt;Internet Explorer&lt;/a&gt; / &lt;a
href="http://www.microsoft.com/office/"&gt;Microsoft Office&lt;/a&gt; vs. Linux / Mozilla
/ OpenOffice) but any given corporation could have tens or hundreds or even &lt;b&gt;hundreds of thousands&lt;/b&gt; (no, that's not a
typo) of custom applications that they need to run their business on every day.
And if they couldn't install or use those applications, they would never move
to the next version of Windows, which would mean I'd be out on my ear and
deported back to &lt;st1:country-region w:st="on"&gt;&lt;st1:place w:st="on"&gt;Australia&lt;/st1:place&gt;&lt;/st1:country-region&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Sure, we could definitely make
the experience much better than the dog-ugly and confusing AuthentiCode dialog
we have today, and it's something we really need to work on in the future, but
at the end of the day the user has to take on some responsibility. Driving a dump
truck into a bank vault and then telling the police &amp;quot;I didn't know how to
use the brakes!&amp;quot; doesn't work very well (go on, prove me wrong!), so installing
malicious software and claiming &amp;quot;I didn't know how to stop myself from doing
it!&amp;quot; shouldn't work well either. (I'm deliberately being harsh here -- I
really do believe we must do a better job of helping users make informed
decisions when it comes to their computer use -- but the fundamental problem
remains: if people want to take actions of questionable merit and / or don't
want to take the time to understand even the basics of computer security,
there's not much we can do to help them).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Anyway, back to the story. If
you tell IE to install the ACOUD then you are toast, plain and simple, and it's
not our fault. Time to &lt;a
href="http://www.cert.org/tech_tips/root_compromise.html"&gt;reformat your machine&lt;/a&gt;
(oh wait, the control already did that for you -- how helpful!) and start
again.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;And of course if the third one
happens, it's just like second one except you were saved the inconvenience of
clicking &amp;quot;Yes&amp;quot; :-).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So in this case, the problem is
&lt;b&gt;getting the control on the user's
machine&lt;/b&gt;. If the bad guy can trick the user into installing the bad code, or
they can trick the computer into installing it automatically, they've already
won. What we try to do with our product designs is of course make it impossible
for the attacker to do this without the user being made aware of the possible
consequences. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So far, so good.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: I just had a really bad espresso experience -- note &lt;b&gt;there is no &amp;quot;x&amp;quot; in
&amp;quot;espresso&amp;quot;&lt;/b&gt;! Although I have a &lt;a
href="http://wholelattelove.com/packages/expobar_mazzer.htm"&gt;pretty decent coffee
machine&lt;/a&gt;, I just switched beans and so the grind wasn't right. Grrrr]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Now the second big scenario I
mentioned was when the ACOUD is already installed on your machine. In this
scenario, we assume that the ACOUD is actually a well-designed piece of software
that you installed and perhaps regularly use. This might sound shocking, but
remember the example of the &lt;st1:State w:st="on"&gt;&lt;st1:place w:st="on"&gt;&lt;b&gt;DEL&lt;/b&gt;&lt;/st1:place&gt;&lt;/st1:State&gt; command.
I as a user may have a common requirement of formatting hard drives (especially
if I'm in a tech support role at a large company) and in order to make my job
easier, I may have written a tool that automatically formats drives without any
kind of prompting or warnings, because only I should be able to access the
tool, and I presumably know what I'm doing. It's actually &lt;b&gt;VERY HARD&lt;/b&gt; to convince people -- even really smart people -- that
the ACOUD is a legitimate piece of software in this instance. It intuitively
seems to go against everything we know about security. &amp;quot;You mean as soon
as I call into this control it formats my hard drive? Without prompting?!? How
can that be a good idea?!?&amp;quot; But trust me, there's nothing wrong with such
a control if it is &lt;b&gt;properly designed and
protected&lt;/b&gt;. (This also applies in the case where you have some &lt;a
href="http://www.eeye.com/html/Research/Advisories/AD20020502.html"&gt;slightly
less risky control that just happens to have an exploitable bug in its
initialisation routines&lt;/a&gt;, but again the absolute coolness of the ACOUD
trumps such a boring example in this case).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So anyway, we have the ACOUD
sitting on our machine, and now the attack we are worried about is a web page
or Office document that somehow manages to create and initialise an instance of
that control &lt;b&gt;without our consent&lt;/b&gt;.
Holy whack exploitable software, Batman. We've got a problem. This is where the
&lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/workshop/components/activex/safety.asp"&gt;Safe
for Initialization&lt;/a&gt; (SFI) attribute is used by Internet Explorer -- by
default it will not try and initialise controls with data embedded in the web
page because, in general, controls are not very good at protecting themselves
against malicious input (overly large values that cause buffer overruns,
spoofed URLs that accept leaked information, etc). So unless a control says
&amp;quot;Yep, it's OK to feed me random garbage!&amp;quot; IE will not initialise a
control with untrusted data. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;In this case, the problem is &lt;b&gt;allowing unauthorised agents to access more-privileged
software in unexpected and dangerous ways&lt;/b&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If we design software that
somehow fails to honour the semantics of SFI then we are in deep, deep trouble.
And this is very hard to explain to someone -- &lt;/span&gt;yes &lt;span&gt;the user installed the ACOUD, but it doesn't pose a
security problem until &lt;b&gt;YOUR CODE&lt;/b&gt;
decides to activate it on behalf of &lt;a
href="http://www.hackmeplease_noreallyimbeggingyou.com/"&gt;www.hackmeplease_noreallyimbeggingyou.com&lt;/a&gt;.
Eventually the point is made, often via analogies with knives, scissors, axes,
teddy bears (yes, teddy bears) and other real-world objects, but it takes a
tremendous amount of effort. Which is one of the reasons why I'm writing this.&lt;/span&gt;&lt;span
lang=EN-US&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Another aside -- I initially
tried searching for &lt;a
href="http://www.google.com/search?hl=en&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8&amp;amp;q=site%3Amicrosoft.com+safe+for+initialisation"&gt;Safe
for Initialisation&lt;/a&gt; (the &lt;b&gt;correct&lt;/b&gt; spelling)
and ended up with a bunch of links to research papers, presumably written by
people in Microsoft &lt;st1:place w:st="on"&gt;&lt;st1:country-region w:st="on"&gt;UK&lt;/st1:country-region&gt;&lt;/st1:place&gt;
:-). &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So there is a big difference
between a hacker installing malicious code of their own design, and a hacker
coopting otherwise benign software for evil doings of their own design. In once
case we throw up our hands and say &amp;quot;the user made a bad trust
decision!&amp;quot; and there's really nothing else we can do (other than provide
additional mitigations via a defence-in-depth strategy), and in the other case
we throw up our hands and say &amp;quot;Ouch, we gotta fix that before we
ship!&amp;quot; (and also consider other mitigations as part of a defence-in-depth
strategy). For some reason I've started writing &amp;quot;defence&amp;quot; as
&amp;quot;defense&amp;quot;; I don't know why. I wish I would stop doing it, but at
least Word corrects it for me so I don't look silly when this finally goes up
on the web.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: Don't kid yourself -- you DO look silly]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Anyway, since I've rambled
about random stuff for quite some time now, it only seems fair that I should ramble
some more. Here's a common thread that you might have found on one of the
Microsoft scripting newsgroups a few years ago:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;FrustratedDev&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: I built a cool
ActiveX control for my company, but it won't load in the browser. I keep
getting security errors. Help!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;HelpfulPoster1&lt;/span&gt;&lt;/b&gt;&lt;span&gt;:
Just lower your security settings and it will work!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;Me&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: Nooooo,
don't do that! You'll open yourself up to malicious code in the future.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;HelpfulPoster2&lt;/span&gt;&lt;/b&gt;&lt;span&gt;:
Just sign your control with a certificate!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;Me&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: Nooooo,
don't do that! Signatures have nothing to do with whether a control will load
in IE or not; it determines whether the control can be downloaded and installed
or not&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;HelpfulPoster3&lt;/span&gt;&lt;/b&gt;&lt;span&gt;:
Just mark it &amp;quot;Safe for Scripting&amp;quot;!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;Me&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: Nooooo,
don't do that! Your code almost certainly isn't safe for untrusted callers.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The point being, well.... I
forget now. But the moral of the story is don't sign ActiveX controls or mark
them as Safe for Scripting unless you really REALLY need to enable arbitrary
users to download your code and have it run against arbitrary web pages. And unless
you're &lt;a
href="http://www.microsoft.com/windows/windowsmedia/download/default.asp"&gt;Microsoft&lt;/a&gt;
or &lt;a
href="http://www.macromedia.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"&gt;Macromedia&lt;/a&gt;
or &lt;a href="http://www.apple.com/quicktime/download/"&gt;Apple&lt;/a&gt; or a similar
type of company trying to reach millions of desktops across the world, and you
have the resources and expertise to thoroughly review your code for security
vulnerabilities that probably means &amp;quot;not you&amp;quot;. (And even if it is
you, you probably missed a bug or two along the way). &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;In case you care, more info on
building secure ActiveX controls can be found &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/workshop/components/activex/safety.asp"&gt;here&lt;/a&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Get to the point already!!!&lt;/h3&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: Yeah, you rambling fool! Get to the point!]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;OK, so something about
repurposing ActiveX controls. Let's start with an example. A rather extreme example
that is used quite often internally here in our team at Microsoft to get across
the general idea of the badness of repurposing.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Let's say that OTG (our
internal IT department) builds a &amp;quot;Format your Drive&amp;quot; web page, using
a signed control that is marked &amp;quot;Safe for Scripting&amp;quot; (so that it
loads without any errors). When you go to the Helpdesk web site and click on
the &amp;quot;I need to format my drive&amp;quot; link, it downloads the helpful web
page for you. The document has some informational text about what formatting
means, why it is a dangerous thing to do, and so on. It also contains two buttons
labelled &amp;quot;Yes&amp;quot; and &amp;quot;No&amp;quot;, and it links to the code that does
the actual formatting. The code is signed with the internal corporate
signature, so all users at Microsoft implicitly trust it. When the user clicks
the &amp;quot;Yes&amp;quot; button, it calls into the code to format the drive, which
is perfectly acceptable and the right thing to do, since the user has been made
aware of the consequences and has made an informed decisions.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The problem is that some pesky
trickster creates a copy of the web page and replaces all the text about hard
drive formatting with some text about downloading pictures of famous
celebrities in various stages of undress. They maintain a link to the original
formatting ActiveX control (which, remember, is signed and trusted), and send a
link to the page around to all the people in their team. An unsuspecting user or
three hundred decides to open the link and click the &amp;quot;Yes&amp;quot; button, in
eager anticipation of seeing Margaret Thatcher in her winter underwear. (My
apologies to those readers who just passed out). This of course invokes the
original &lt;b&gt;FormatDrive()&lt;/b&gt; function in
the trusted control, and the user is toast. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;A more subtle (but perhaps more
realistic) scenario is where a less obviously dangerous piece of code gets
repurposed from another document that is expected to contain code. For example,
let's say that the IT department builds a new kind of budget forecasting web
page that links to custom ActiveX control to implement certain functions
similar to an Excel workbook. Let's also say that the HR department has built a
web page (using another control) that enables users to balance their benefits
(for the non-US people: that means your non-salary compensation, such as a
medical plan, gym / health club membership, life insurance, etc.). And let's
also assume that the HR control takes the URL of the web server it should
contact as a parameter to the &amp;lt;object&amp;gt; tag in the HTML document.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Now assume that malicious user
Bob wants to know how much money Alice earns, so he modifies a copy of the HR web
page so it looks like the budget web page (by formatting so that it looks like
a budget spreadsheet) but he updates the &amp;lt;PARAM&amp;gt; tag to point to his own
web server and sends the document to Alice with a note saying &amp;quot;Please check
these estimates and get back to me&amp;quot;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Now we see the problem. &lt;st1:place
w:st="on"&gt;&lt;st1:City w:st="on"&gt;Alice&lt;/st1:City&gt;&lt;/st1:place&gt; opens the web page,
and instead of the Budget code being executed, the HR code starts executing and
uploads her personal information -- salary, stock options, health coverage,
etc. -- to the web server that Bob controls. Remember the HR code is already
signed and trusted; this is not a malicious code injection attack, but a
repurposing attack. Even assuming that &lt;st1:City w:st="on"&gt;&lt;st1:place w:st="on"&gt;Alice&lt;/st1:place&gt;&lt;/st1:City&gt;'s
machine was setup to prompt before executing code, she &lt;b&gt;expects&lt;/b&gt; the budget web page to execute code and so will most likely
consent to the request, even though it's executing &lt;b&gt;the wrong code&lt;/b&gt;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I'm sure you can imagine other
scenarios. The possibilities are endless! :-)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: I think that should be &amp;quot;:-(&amp;quot;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;As I explained in my &lt;a
href="http://blogs.gotdotnet.com/ptorr/commentview.aspx/9f6e31e8-937e-4328-b457-132360cd51ed"&gt;previous
blog entry&lt;/a&gt;, insofar as VSTO goes we try somewhat to stop this attack from &lt;a
href="http://msdn.microsoft.com/library/en-us/dv_wrcore/html/wrconDeployingSecurely.asp?frame=true"&gt;e-mail
attachments and random web sites&lt;/a&gt;, but it doesn't help if users &lt;a
href="http://msdn.microsoft.com/library/en-us/dv_wrcore/html/wrconWhiteRabbitSecurityModels.asp?frame=true"&gt;copy
documents to their desktop or start publishing such malicious documents to
trusted internal web sites&lt;/a&gt;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;And now you know why all my
blogs are posted past &lt;st1:mswterms Hour="0" Minute="00" w:st="on"&gt;midnight&lt;/st1:mswterms&gt;
-- I can't sleep with all these nightmares about code repurposing going on in
my head!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;One last thing for the evening
-- a real life tale of a security bug that could have been... in my very own
WordBlogX!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The current version of WordBlogX
on &lt;a
href="http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=50759CA7-6668-425A-B730-47E9B52B4EDB"&gt;GotDotNet&lt;/a&gt;
is pretty bad, mostly because it is lacking useful features. One feature I've
already added in the build on my machine is the ability to put the URL of the
blog server in a config file, thereby enabling people to post blogs to servers
other than GotDotNet without recompiling the source code. Another feature I
really want to add (but haven't done so yet) is a &amp;quot;remember my
password&amp;quot; feature that &lt;a
href="http://msdn.microsoft.com/library/en-us/security/security/credwrite.asp?frame=true"&gt;securely
stores my credentials&lt;/a&gt; on the local machine so I don't have to type them in
every time I make a post. I'm going to implement this feature RSN (&lt;b&gt;R&lt;/b&gt;eal &lt;b&gt;S&lt;/b&gt;oon &lt;b&gt;N&lt;/b&gt;ow; often used
sarcastically to mean &amp;quot;never&amp;quot; but in this case I really do hope to do
it soon!). &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Can anyone see the problem with
this design? Anyone? &lt;a href="http://www.imdb.com/title/tt0091042/"&gt;Beuller&lt;/a&gt;?&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The problem is that anyone who
gets a copy of the assembly can put it on a server of their control, modify the
config file to point to a web server of under their control, send an arbitrary
document that links to this code to anyone who uses WordBlogX, and then wait
for the cached passwords to flow in. The attacker simply needs to have a button
on their document with the programmatic name of &lt;b&gt;cmdPost&lt;/b&gt;&lt;/span&gt; and somehow socially engineer the user into clicking
it (&amp;quot;Free life-time supply of dental floss -- click here now!&amp;quot;).&lt;span&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: Note that the root badness here is trusting the URL in the config
file; sending usernames and passwords is just a bad side-effect that drives the
point home]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Is this a bad design? Yes, it
is.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Would the average developer,
faced with similar requirements, come up with the same design? Quite probably.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Would this same developer
threat model their code and try to mitigate against this attack? I don't think
so.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Luckily for me I have the
assembly for WordBlogX &amp;quot;installed&amp;quot; in a particular directory on my
system, and it will only ever try to load the configuration file from that
directory. The assembly is not signed and I do not trust it to load from any
other locations (eg, malicious web sites), so I should be safe from this kind
of attack for the time being (as should anyone else who installs WordBlogX in
the future). But if I was the IT department in a large corporation, I'd
probably just sign the code with the corporate certificate, and the code would
be trusted from any location inside the LocalIntranet Zone (or perhaps on a
server where malicious users have some degree of write access), in which case
it wouldn't be long before the code was exploited.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I will probably add a
confirmation dialog box to WordBlogX that displays the remote URL before retrieving
credentials or sending any information to the server just to make sure, but
this will no doubt annoy &lt;a href="http://blogs.gotdotnet.com/robmen/"&gt;some users&lt;/a&gt;
and they will turn off the confirmation. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;(A lot of people downplay the
likelihood or severity of internal attacks because, well, you only ever hear
about high-profile public attacks in the news. But don't kid yourself --
attacks from people &lt;b&gt;inside&lt;/b&gt; the
firewall are much more common and much more likely to cost you big money than attacks
from faceless hackers sitting half way across the world).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thus ends tonight's effort.
It's been long and random, and I probably scared the willies out of some
people, but that's the way life is.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;P.S. I managed to talk about
teddy bears in the context of security when talking to a fellow PM about
trusting the &amp;quot;Safe for Scripting&amp;quot; flag on controls. His argument was
that SFS buys you nothing because hackers will always just set that bit and so
therefore you are hosed when the control loads in IE. This is a concrete
example of failing to understand the differences between installing malicious
code and repurposing trusted code, as I tried to outline in the ACOUD example.
Anyway, we had been talking about knives and how he wouldn't trust his young
child with a big kitchen knife, so in a moment of desperation I came up with
&amp;quot;The Teddy Bear Defence&amp;quot;. When you buy a teddy bear from the shop, it
comes with a safety tag that says &amp;quot;suitable for children 3 years and
older&amp;quot; or something similar. As part of the purchasing act, you
(implicitly) trust that the manufacturer is not lying about the toy being
suitable for anyone 3 years of age or older. If the toy was manufactured by an
evil company, all bets are off as to whether it is even safe for ANYONE to have
the teddy bear, no matter what their age -- maybe it spontaneously combusts on
the third Sunday of the month. In this case you made a bad purchasing / trust
decision. But if the toy was manufactured by a responsible company, you can use
the information printed on the warning label to deduce that it is OK to give the
teddy bear to your 5-year-old but not your 2-year-old. And there you have it.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: This guy is ccccrrrraaaaaaaazzzzzyyyy!]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;P.P.S. Who's this
&amp;quot;Ed&amp;quot; fellow, and why does he keep popping up in my blog?&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;[Ed: Mmmmmuahahahahahaaaaa.......!!!!!]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56270" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/WordBlogX/default.aspx">WordBlogX</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Another debugging tip</title><link>http://blogs.msdn.com/ptorr/archive/2003/10/13/56266.aspx</link><pubDate>Mon, 13 Oct 2003 23:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56266</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56266.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56266</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56266</wfw:comment><description>
&lt;p&gt;I wrote about a few &lt;a
href="http://blogs.gotdotnet.com/ptorr/PermaLink.aspx/fc6c7061-5943-435b-9da6-5646b5cc77ab"&gt;debugging
tips for VSTO&lt;/a&gt; the other day. Something else just came up this morning that I
should add. Does this scenario sound familiar?&lt;/p&gt;
&lt;ul type=disc&gt;
 &lt;li&gt;You decide
     to create a new VS project&lt;/li&gt;
 &lt;li&gt;You click
     through all the default dialogs, ignoring the silly default name (you'll
     change it later)&lt;/li&gt;
 &lt;li&gt;You
     build and debug &lt;b&gt;WordProject238&lt;/b&gt;
     for a while until it is looking good&lt;/li&gt;
 &lt;li&gt;You give
     the finished project to someone and they complain that the name is not
     very descriptive&lt;/li&gt;
 &lt;li&gt;You
     rename the document to &lt;b&gt;MyCoolTemplate.dot&lt;/b&gt;
     and rename the assembly to &lt;b&gt;MyCoolAssembly.dll&lt;/b&gt;&lt;/li&gt;
 &lt;li&gt;You
     test the document and it fails to find &lt;b&gt;WordProject238_bin\WordProject238&lt;/b&gt;&lt;/li&gt;
 &lt;li&gt;You
     kick yourself for forgetting the &lt;b&gt;AssemblyLinkLocation&lt;/b&gt;,
     and make the custom properties point to &lt;b&gt;MyCoolTemplate_bin\MyCoolTemplate&lt;/b&gt; instead&lt;/li&gt;
 &lt;li&gt;Your
     code still fails to run with some spurious &amp;quot;Can't be found or
     loaded&amp;quot; error&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Well guess what? You just broke a fundamental rule of the
CLR -- the &amp;quot;assembly name&amp;quot; (the thing you pass to &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemReflectionAssemblyClassLoadTopic.asp"&gt;Assembly.Load&lt;/a&gt;)
must match the internal &amp;quot;assembly name&amp;quot; (the thing inside the &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconassemblymanifest.asp"&gt;Manifest&lt;/a&gt;).
The compiler sets the Manifest's name to be the same as the DLL's name when you
build the project, and manually re-naming the DLL after the fact will cause
problems. &lt;/p&gt;
&lt;p&gt;You have to go to the Project Properties inside VS, change
the output name to &lt;b&gt;MyCoolTemplate.dll&lt;/b&gt;,
and then re-build the project. (This should also fix up the custom properties
for you).&lt;/p&gt;
&lt;p&gt;This &amp;quot;bug&amp;quot; came up several times during the
product cycle, and it just came up again today. If it ever comes up again, I'll
have a URL to point to ;-)&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56266" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>More VSTO Press</title><link>http://blogs.msdn.com/ptorr/archive/2003/10/13/56265.aspx</link><pubDate>Mon, 13 Oct 2003 18:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56265</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56265.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56265</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56265</wfw:comment><description>
&lt;p&gt;VSTO has been picked by a few more places; you can pick your
favourite link from &lt;a
href="http://news.google.com/news?hl=en&amp;amp;lr=&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8&amp;amp;newwindow=1&amp;amp;safe=off&amp;amp;num=30&amp;amp;newsclusterurl=http://www.itnews.com.au/storycontent.asp%3FID%3D10%26Art_ID%3D15757"&gt;Google
News results&lt;/a&gt; or just go straight to the &lt;a
href="http://www.itnews.com.au/storycontent.asp?ID=10&amp;amp;Art_ID=15757"&gt;Australian
version&lt;/a&gt; :-)&lt;/p&gt;
&lt;p&gt;Now if this would somehow make it to &lt;a
href="http://www.slashdot.org/"&gt;Slashdot&lt;/a&gt;, I could retire happy.&lt;/p&gt;
&lt;p&gt;I would have written an entry last night had my laptop
keyboard not died on me; it seems to be doing better today, so maybe this
evening I'll waffle some more.&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56265" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Successfully debugging VSTO projects</title><link>http://blogs.msdn.com/ptorr/archive/2003/10/06/56250.aspx</link><pubDate>Mon, 06 Oct 2003 09:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:56250</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/56250.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=56250</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=56250</wfw:comment><description>
&lt;p&gt;It seems that everyone I know who is writing a blog has a
long list of things they want to talk about, and the list grows faster than
they can write entries. This is fundamentally different from the way newsgroup
postings work, where it's very much a reactionary thing (someone posts a
question and then you post the answer). I've often wanted a &amp;quot;low
priority&amp;quot; flag for news posts (the same way e-mail has low priority flags)
so that I could just write random stuff for people to read at their leisure.
But of course then you'd have to have a corresponding &amp;quot;high priority&amp;quot;
flag, and everyone and their dog would abuse it.&lt;/p&gt;
&lt;p&gt;But now I have this blog. Hmmm.&lt;/p&gt;
&lt;p&gt;My wish list contains some things that will take a while to
write about, but nothing like what &lt;a href="http://blogs.gotdotnet.com/cbrumme/"&gt;Chris
Brumme&lt;/a&gt; is able to do on a regular basis. Even his e-mail replies to casual
questions are incredibly long and detailed, and we're very lucky to have him at
Microsoft!&lt;/p&gt;
&lt;p&gt;Anyway, a small topic for tonight. One thing I'd like to do
is talk a lot about some of the finer points of VSTO (in particular its
security model), but unfortunately (!!!) &lt;a
href="http://msdn.microsoft.com/library/en-us/dv_wrcore/html/oriIntegratingOfficeComponents2.asp?frame=true"&gt;the
documentation&lt;/a&gt; is actually pretty detailed and so I'm not sure how much
value I can add. Oh well, we'll see how often things come up on the newsgroups
and in internal support e-mail aliases.&lt;/p&gt;
&lt;p&gt;Oh well, on to my 3 main tips for the evening:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Swallowed Exceptions&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;If you have some code in your solution that generates an
exception, and that exception propagates back to the caller (Word or Excel)
then you will not be notified about it. This is in contrast to VBA which will
tell you when your code has messed up, and it often confuses people -- their
code just silently dies.&lt;/p&gt;
&lt;p&gt;As Chris points out in his latest &lt;a
href="http://blogs.gotdotnet.com/cbrumme/PermaLink.aspx/d5fbb311-0c95-46ac-9c46-8f8c0e6ae561"&gt;treatise
on exceptions&lt;/a&gt;, the CLR tries to interop with the unmanaged world when it
comes to exception propagation, and the way that managed exceptions are
returned to the COM world is via failed HRESULTs and the &lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap11_31in.asp"&gt;IErrorInfo
interface&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;For better or worse, when Word or Excel receives a failed
HRESULT from a method call (usually an event handler in this case) they just
ignore it and move on. In the VBA case they have a much tighter integration
with the runtime portion and VBA will do its thing when it realises it's about
to lose control of execution, and so you get the error message (which of course
is very annoying if you're an end-user because you have no idea what a Type
Mismatch is, and can't do anything about it).&lt;/p&gt;
&lt;p&gt;So in VSTO, if you have any code that is called by Word or
Excel, you should wrap it in try-catch blocks so that you can display an error
or do other processing as appropriate before the error is forever lost in the
transition to unmanaged code. Another trick is to &lt;a
href="http://msdn.microsoft.com/library/en-us/dv_wrcore/html/wrtskhandlingerrorsinwhiterabbit.asp?frame=true"&gt;turn
on the &amp;quot;Break on 1st chance exceptions&amp;quot; setting&lt;/a&gt;, although this
will get you more exceptions than you need. Fine-tuning the exceptions that
will break into the debugger by expanding the TreeView and unselecting some of
the exception types you are uninterested in can help.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Failing to execute&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A common problem people have is that their assembly does not
execute at all. They got the original solution working in Visual Studio (where
we handle the basic security policy changes for you), but when they move it to
another machine or a different directory it fails to load. The most likely
reason for this is that policy was not updated correctly, and the thing I
always ask people to do is run the following commands and send me the results:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;caspol -all -lg&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;caspol -rsg &lt;i&gt;path_to_assembly&lt;/i&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;What this will tell me is what their security policy looks
like (&lt;b&gt;lg&lt;/b&gt; == &lt;b&gt;list groups&lt;/b&gt; == list all policy rules), and then how the CLR thinks
the evidence of the assembly maps to those rules (&lt;b&gt;rsg&lt;/b&gt; == &lt;b&gt;resolve groups&lt;/b&gt; ==
list groups the assembly matches). This tells me whether or not they have set
up policy correctly, and whether or not their assembly is matching the code
groups they think it should match. Most problems are caught here for one of
three reasons:&lt;/p&gt;
&lt;ol start=1 type=1&gt;
 &lt;li&gt;A
     network rule (eg, &lt;a href="http://server/"&gt;http://server/&lt;/a&gt; --&amp;gt;
     FullTrust) was added to the MyComputer zone, but it's in the LocalIntranet&lt;/li&gt;
 &lt;li&gt;There's
     a typo in the filename or URL&lt;/li&gt;
 &lt;li&gt;The
     asterisk (*) was not added after a directory to indicate &amp;quot;and all
     folders under here&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I'll show an example of a fourth problem I've only seen once,
but the effect is the same as for the three cases above:&lt;/p&gt;
&lt;p&gt;A simplified output of &lt;b&gt;caspol
-all -lg&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;st1:place w:st="on"&gt;&lt;st1:City w:st="on"&gt;&lt;b&gt;Enterprise&lt;/b&gt;&lt;/st1:City&gt;&lt;/st1:place&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;All_Code: FullTrust&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Machine&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;All_Code: Nothing&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyComputer: FullTrust&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LocalIntranet: LocalIntranet&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a
href="http://localhost/*"&gt;http://localhost/*&lt;/a&gt;: FullTrust&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TrustedSites: LocalIntranet&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RestrictedSites: Nothing&lt;/p&gt;
&lt;p&gt;&lt;b&gt;User&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;All_Code: FullTrust&lt;/p&gt;
&lt;p&gt;A simplified output of &lt;b&gt;caspol
-rsg &lt;a href="http://localhost/myassembly.dll"&gt;http://localhost/myassembly.dll&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;st1:City w:st="on"&gt;&lt;st1:place w:st="on"&gt;&lt;b&gt;Enterprise&lt;/b&gt;&lt;/st1:place&gt;&lt;/st1:City&gt;&lt;b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;All_Code&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Machine&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;All_Code&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TrustedSites&lt;/p&gt;
&lt;p&gt;&lt;b&gt;User&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;All_Code&lt;/p&gt;
&lt;p&gt;Immediately it is obvious to the trained eye that the user
thought &lt;a href="http://localhost/"&gt;http://localhost/&lt;/a&gt; was in the
LocalIntranet zone (which it is by default), but for one reason or another they
have added it to the TrustedSites zone in IE. The answer is simply to move the
localhost rule from LocalIntranet to TrustedSites, and you are golden.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Other random security
failures&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;If your main assembly loads, but you get random errors at
some other time (especially if you are using 3rd party components or some code
that may be automatically generating assemblies via ICodeCompiler or VSA) then
you may be able to use the technique I describe in &lt;a
href="http://groups.google.com/groups?hl=en&amp;amp;lr=&amp;amp;ie=UTF-8&amp;amp;selm=eHZ0VqSZDHA.736%40TK2MSFTNGP09.phx.gbl"&gt;this
newsgroup post&lt;/a&gt;. Essentially you can &lt;b&gt;temporarily&lt;/b&gt; grant unrestricted
permissions to all code on your local machine and then at some opportune time
in your program you dump out the evidence used to load all the
&amp;quot;interesting&amp;quot; assemblies. For example, if you use a component that
dynamically compiles and loads assemblies via &lt;a
href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemCodeDomCompilerICodeCompilerClassTopic.asp?frame=true"&gt;ICodeCompiler&lt;/a&gt;,
you will probably find some randomly-named assembly loaded into your AppDomain
with a certain set of evidence. &lt;/p&gt;
&lt;p&gt;Depending on what control you have over the generated
assembly, you may be able to force it to be generated in a particular location
which you can then trust. It is likely to be tricky to get these kinds of
solutions working though, and your best bet in this instance may be to create a
new AppDomain with its own (probably default) security policy that can load the
dynamically generated code. But then of course you'll have problems marshalling
the stuff between AppDomains.... sigh. &lt;/p&gt;
&lt;p&gt;----------&lt;/p&gt;
&lt;p&gt;Something else I may talk about in more detail at some stage
is the &lt;a
href="http://msdn.microsoft.com/library/en-us/odc_vsto2003_ta/html/odc_VSTMultCR.asp"&gt;Excel
/ .NET mismatched locale issue&lt;/a&gt;. This is a problem that came up during beta,
and spawned many person months of discussion and brainstorming to come up with
a workable solution. At the end of the day, the best we could do was document
the problem (ie, the link above) and try and work something out longer-term.
The problem is really quite hard to solve, and maybe I'll delve into it in a
bit more detail later on. (Actually there is a fairly simple solution that will
work in most cases, but it &amp;quot;feels&amp;quot; like a hack and it just wasn't
feasible at this point in time).&lt;/p&gt;
&lt;p&gt;Oh and some trivia for the evening:&lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;1)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;&lt;a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemsecuritypermissionsiunrestrictedpermissionclasstopic.asp"&gt;IUnrestrictedPermission&lt;/a&gt;
is the thing in the CLR that lets a permission become part of the &lt;b&gt;FullTrust&lt;/b&gt; pseudo permission set. &lt;/p&gt;
&lt;p&gt;&lt;![if !supportLists]&gt;&lt;span&gt;&lt;span&gt;2)&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]&gt;There
are no Microsoft-provided implementations of &lt;a
href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemCodeDomCompilerICodeParserClassTopic.asp?frame=true"&gt;ICodeParser&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notes for #1: Pretty much all permissions except &lt;a
href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemSecurityPermissionsStrongNameIdentityPermissionClassTopic.asp"&gt;StrongnameIdentityPermission&lt;/a&gt;
implement the IUnrestrictedPermission interface. The difference between the &lt;b&gt;Everything&lt;/b&gt; permission set and the &lt;b&gt;FullTrust&lt;/b&gt; pseudo permission set is that
&lt;b&gt;Everything&lt;/b&gt; contains a static list of
all permissions that Microsoft ships out of the box but no 3rd party
permissions. &lt;b&gt;FullTrust&lt;/b&gt; on the other
hand is a dynamically computed list that includes all permissions that
implement &lt;b&gt;IUnrestrictedPermission&lt;/b&gt;,
including any 3rd party permissions. You should probably never use the &lt;b&gt;Everything&lt;/b&gt; permission set unless you
have a really good reason to, and if you ever find yourself in the position of
having to implement your own permission (not something you'd do for an ordinary
application) then you should strongly consider implementing &lt;b&gt;IUnrestrictedPermission&lt;/b&gt; if the
semantics of your permission mean that &lt;b&gt;FullTrust&lt;/b&gt;
code should get it (and since &lt;b&gt;FullTrust&lt;/b&gt;
code can do anything it wants, including lie about evidence, call unmanaged
code, read and write random memory locations, etc. it can do whatever it is
you're trying to prevent anyways, so you shouldn't really think you're buying
any additional security by not implementing &lt;b&gt;IUnrestrictedPermission&lt;/b&gt;). &lt;/p&gt;
&lt;p&gt;Notes for #2: Every now and then &lt;a
href="http://groups.google.com/groups?q=group:microsoft.public.dotnet.*+ICodeParser"&gt;someone
asks a question about ICodeParser&lt;/a&gt;, and how they go about getting their
eager little mitts on an instance for C# or VB (strangely no-one ever seems to
ask about JScript...&amp;lt;sniff&amp;gt;). Anyway, you can't. Obviously someone
designed that interface because they had planned to ship something along the
lines of a source-code-to-CodeDOM translator, but at some point in the long and
arduous journey of shipping a product it got left behind. I even remember
hearing about a feature of VS where you could copy VB .NET source code and
paste it as C# (and vice versa), but this was a year or more before VS 7.0 shipped
and it's still not in the product today. I may have even seen a demo at one
point in time, but I don't know if I'm imagining that or not ;-).&lt;/p&gt;
&lt;p&gt;That's it for now!&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=56250" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Office/default.aspx">Office</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item></channel></rss>