<?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>Larry Osterman's WebLog : Software Engineering</title><link>http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx</link><description>Tags: Software Engineering</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>I can make it arbitrarily fast if I don’t actually have to make it work.</title><link>http://blogs.msdn.com/larryosterman/archive/2009/09/29/i-can-make-it-arbitrarily-fast-if-i-don-t-actually-have-to-make-it-work.aspx</link><pubDate>Wed, 30 Sep 2009 00:49:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9901016</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>27</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/9901016.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=9901016</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=9901016</wfw:comment><description>&lt;p&gt;Digging way back into my pre-Microsoft days, I was recently reminded of a story that I believe was told to me by &lt;a href="http://en.wikipedia.org/wiki/Mary_Shaw_(computer_scientist)"&gt;Mary Shaw&lt;/a&gt; back when I took her Computer Optimization class at Carnegie-Mellon…&lt;/p&gt;  &lt;p&gt;During the class, Mary told an anecdote about a developer “Sue” who found a bug in another developer’s “Joe” code that “Joe” introduced with a performance optimization.&amp;#160; When “Sue” pointed the bug out to “Joe”, his response was “Oops, but it’s WAY faster with the bug”.&amp;#160; “Sue” exploded “If it doesn’t have to be correct, I can calculate the result in 0 time!” [1].&lt;/p&gt;  &lt;p&gt;Immediately after telling this anecdote, she discussed a contest that the CS faculty held for the graduate students every year.&amp;#160; Each year the CS faculty posed a problem to the graduate students with a prize awarded to the grad student who came up with the most efficient (fastest) solution to the problem.&amp;#160; She then assigned the exact same problem to us:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“Given a copy of the “Declaration of Independence”, calculate the 10 most common words in the document”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We all went off and built programs to parse the words in the document, inserting them into a tree (tracking usage) and read off the 10 most frequent words.&amp;#160; The next assignment was “Now make it fast – the 5 fastest apps get an ‘A’, the next 5 get a ‘B’, etc.”&lt;/p&gt;  &lt;p&gt;So everyone in the class (except me :)) went out and rewrote their apps to use a hash table so that their insertion time was constant and then they optimized the heck out of their hash tables[2].&lt;/p&gt;  &lt;p&gt;After our class had our turn, Mary shared the results of what happened when the CS grad students were presented with the exact same problem.&lt;/p&gt;  &lt;p&gt;Most of them basically did what most of the students in my class did – built hash tables and tweaked them.&amp;#160; But a couple of results stood out.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The first one simply hard coded the 10 most common words in their app and printed them out.&amp;#160; This was disqualified because it was perceived as breaking the rules.&lt;/li&gt;    &lt;li&gt;The next one was quite clever.&amp;#160; The grad student in question realized that they could write the program much faster if they wrote it in assembly language.&amp;#160; But the rules of the contest required that they use Pascal for the program.&amp;#160; So the grad student essentially created an array on the stack and introduced a buffer overflow and he loaded his assembly language program into the buffer and used that as a way of getting his assembly language version of the program to run.&amp;#160; IIRC he wasn’t disqualified but he didn’t win because he circumvented the rules (I’m not sure, it’s been more than a quarter century since Mary told the class this story).&lt;/li&gt;    &lt;li&gt;The winning entry was even more clever.&amp;#160; He realized that he didn’t actually need to track all the words in the document.&amp;#160; Instead he decided to track only some of the words in the document in a fixed array.&amp;#160; His logic was that each of the 10 most frequent words were likely to appear in the first &amp;lt;n&amp;gt; words in the document so all he needed to do was to figure out what &amp;quot;”n” is and he’d be golden.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So the moral of the story is “Yes, if it doesn’t have to be correct, you can calculate the response in 0 time.&amp;#160; But sometimes it’s ok to guess and if you guess right, you can get a huge performance benefit from the result”.&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;[1] This anecdote might also come from Jon L. Bentley’s “Writing Efficient Programs”, I’ll be honest and say that I don’t remember where I heard it (but it makes a great introduction to the subsequent story).&lt;/p&gt;  &lt;p&gt;[2] I was stubborn and decided to take my binary tree program and make it as efficient as possible but keep the basic structure of the solution (for example, instead of comparing strings, I calculated a hash for the string and compared the hashes to determine if strings matched).&amp;#160; I don’t remember if I was in the top 5 but I was certainly in the top 10.&amp;#160; I do know that my program beat out most of the hash table based solutions.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9901016" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Fascinating+geek+stuff/default.aspx">Fascinating geek stuff</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Things+you+shouldn_2700_t+do_2E00_/default.aspx">Things you shouldn't do.</category></item><item><title>Digging into the history bin (AKA: Microsoft Developer says that Windows is useless)</title><link>http://blogs.msdn.com/larryosterman/archive/2009/09/01/digging-into-the-history-bin-aka-microsoft-developer-says-that-windows-is-useless.aspx</link><pubDate>Tue, 01 Sep 2009 21:49:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9890021</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/9890021.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=9890021</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=9890021</wfw:comment><description>&lt;p&gt;As I was writing my “25 years of Larry’s history at Microsoft in 1 year chunks” blog posts, I spent a fair amount of time digging through my email archives (trying to figure out exactly what happened at what time).&amp;#160; During this, I ran into a &lt;a href="http://groups.google.com/group/comp.sys.ibm.pc.digest/browse_thread/thread/4e17fc2b0f65305f/e51090ae7795400f?q=larry+osterman&amp;amp;_done=%2Fgroups%3Fq%3Dlarry+osterman%26start%3D50%26&amp;amp;_doneTitle=Back+to+Search&amp;amp;&amp;amp;d"&gt;link to a post&lt;/a&gt; I’d made on the Info-IBMPC mailing list mailing list back in 1992:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Date: Thu, 12 Mar 92 12:44:39 PST      &lt;br /&gt;From: lar&lt;a href="http://groups.google.com/groups/unlock?_done=/group/comp.sys.ibm.pc.digest/browse_thread/thread/4e17fc2b0f65305f/e51090ae7795400f%3Fq%3Dlarry%2Bosterman%26_done%3D%252Fgroups%253Fq%253Dlarry%2Bosterman%2526start%253D50%2526%26_doneTitle%3DBack%2Bto%2BSearch%26%26d&amp;amp;msg=e51090ae7795400f"&gt;...&lt;/a&gt;@microsoft.com       &lt;br /&gt;Subject: What do you do with your windows? (V92 #36) &lt;/p&gt;    &lt;p&gt;|| &amp;gt;From: m&lt;a href="http://groups.google.com/groups/unlock?_done=/group/comp.sys.ibm.pc.digest/browse_thread/thread/4e17fc2b0f65305f/e51090ae7795400f%3Fq%3Dlarry%2Bosterman%26_done%3D%252Fgroups%253Fq%253Dlarry%2Bosterman%2526start%253D50%2526%26_doneTitle%3DBack%2Bto%2BSearch%26%26d&amp;amp;msg=e51090ae7795400f"&gt;...&lt;/a&gt;@Violin.CC.MsState.Edu (Mubashir Cheema) &lt;/p&gt;    &lt;p&gt;||&amp;#160;&amp;#160; I recently acquired Windows 3.0 and I don't seem to understand one      &lt;br /&gt;|| thing.&amp;#160; What is it for?&amp;#160; What do I do with it?&amp;#160; What major advantage       &lt;br /&gt;|| does it have over Dos?&amp;#160; (I don't see any except being able to use mouse       &lt;br /&gt;|| and also the thing is bit more colorful) I think it was made for lazy       &lt;br /&gt;|| people who couldn't learn couple of DOS commands. &lt;/p&gt;    &lt;p&gt;||&amp;#160;&amp;#160; Don't tell me I could multi-task with it. I've been using Amigas      &lt;br /&gt;|| extensively &lt;/p&gt;    &lt;p&gt;I've got to jump in here, even though I suspect that there will probably be some form of an &amp;quot;official&amp;quot; response from MS if anyone in the DOS/Windows group is listening...... :) &lt;/p&gt;    &lt;p&gt;I'm going to be brutally honest about this one. &lt;strong&gt;Basically, Windows by itself IS pretty useless.&lt;/strong&gt; The thing that makes Windows great is the same thing that has made DOS the most popular operating system in history. It's the applications that are available for it. &lt;/p&gt;    &lt;p&gt;GUI's (Graphical User Interfaces) have been proven to be significantly easier for users to understand for beginning users, and are arguably the wave of the future. I don't know of a significant operating system being introduced for the PC market that doesn't have a GUI available on it, be it PM, X, GEM, or Windows. Windows is arguably the best GUI available for DOS based on what I consider the most significant criteria: What applications are available for the platform. &lt;/p&gt;    &lt;p&gt;Consider the list of available windows apps: Excel, WinWord, PageMaker, Corel Draw, WordPerfect, Lotus 123, etc just to name a couple off the      &lt;br /&gt;top of my head. &lt;/p&gt;    &lt;p&gt;You also hit on one of the significant reasons to use Windows - Multi-tasking. &lt;/p&gt;    &lt;p&gt;Windows is a non pre-emptive multi-tasking operating system.&amp;#160; On a 386, it does an ok job of multi-tasking multiple DOS applications, but on a      &lt;br /&gt;286 it functions as a simple task switcher like DOS 5 does.&amp;#160; It really shines when multi-tasking Windows applications however. &lt;/p&gt;    &lt;p&gt;In addition, when you couple the multi-tasking capabilities of Windows with a windows mechanism known as DDE (for Dynamic Data Exchange), you      &lt;br /&gt;can generate some truly incredible synergy between Windows applications. With Win 3.0/Win 3.1 Microsoft has introduced a concept       &lt;br /&gt;known as OLE (Open Linking and Embedding) which allows you to cut and past from multiple &amp;quot;applets&amp;quot; allowing applications to take advantage of       &lt;br /&gt;the capabilities of other shipped applications.&amp;#160; This allows an applet like an equation editor to manage all the information about formatting       &lt;br /&gt;an equation even when the equation is embedded in a word document. With OLE, you can simply double-click on the object and bring up the       &lt;br /&gt;&amp;quot;agent&amp;quot; that manages it (in my example, the equation editor). &lt;/p&gt;    &lt;p&gt;For application developers, Windows gives developers the ability to develop their applications without knowing anything about the      &lt;br /&gt;underlying hardware of the machine - a windows application that runs on a machine with a CGA adapter will also run on a machine with a graphics       &lt;br /&gt;accelerator that runs in 1024x1024 with 24 bits of color. &lt;/p&gt;    &lt;p&gt;In addition, when you write an application for windows, your application instantly will support literally hundreds of printers      &lt;br /&gt;transparently - Windows does all the work for you. &lt;/p&gt;    &lt;p&gt;To re-iterate, Windows as a stand-alone product is not extraordinarily interesting - there are lots of productivity packages that provide      &lt;br /&gt;similar functionality to users, the real benefit of Windows is the applications that run on it. &lt;/p&gt;    &lt;p&gt;I will also point out that there are more than 5000 Windows applications available today and still more will come out with Win 3.1.      &lt;br /&gt;The available windows applications span all ranges of applications from games (Microsoft's Entertainment pack, Berkley-Soft's After Dark, and       &lt;br /&gt;Sierra's Laffer Utilities for Windows) to Spreadsheets (Microsoft Excel, Lotus 1-2-3) to Word processors (Microsoft Word For Windows,       &lt;br /&gt;Lotus Ami), to Desktop publishing (Aldus Pagemaker, Microsoft Publisher), to presentation graphics (Microsoft Powerpoint), to       &lt;br /&gt;development tools (Microsoft Visual Basic) etc...... &lt;/p&gt;    &lt;p&gt;&lt;b&gt;Larry &lt;/b&gt;&lt;b&gt;Osterman&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;Disclaimer:&amp;#160; The opinions above are my own.&amp;#160; They are not necessarily the same as those of Microsoft.&amp;#160; I only work here. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Remember that this was written back in 1992 after Windows 3.0 had come out but before Windows 3.1.&amp;#160; There was no Win32, no web browser, no multimedia support, none of the things that we all take for granted in a modern system.&amp;#160; Back then a display card that supported 1Kx1K with 24bit color was considered a monster display card (and hard disks still came in “megabytes” – I remember buying a 2G hard disk back then for about a thousand dollars).&lt;/p&gt;  &lt;p&gt;Reading this again, I find it vaguely funny that in many ways my feelings about Windows haven’t really changed that much in 18 years – the value of the Windows platform is STILL the applications available for that platform (although the number of applications has grown from the 5000 or so back in 1992 to several million applications).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9890021" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Microsoft+History/default.aspx">Microsoft History</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category></item><item><title>Thinking about Last Checkin Chicken</title><link>http://blogs.msdn.com/larryosterman/archive/2009/06/30/thinking-about-last-checkin-chicken.aspx</link><pubDate>Wed, 01 Jul 2009 01:34:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9810114</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/9810114.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=9810114</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=9810114</wfw:comment><description>&lt;p&gt;Raymond Chen’s post &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2009/06/30/9809037.aspx"&gt;today&lt;/a&gt; started me thinking about “Last Check-in Chicken” again.&amp;#160; Back in the says when we were close to shipping Windows Vista, I wrote about ”&lt;a href="http://blogs.msdn.com/larryosterman/archive/2006/10/25/last-checkin-chicken.aspx"&gt;Last Check-in Chicken&lt;/a&gt;”.&amp;#160; What I didn’t mention was who ultimately won the game for Windows Vista.&lt;/p&gt;  &lt;p&gt;It turns out that the very last change to Windows Vista was actually made by one of the developers on the sound team.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;When you reach the last few days of a project, the bar for taking changes is insanely high – the teams which approve changes to the product get increasingly more conservative about taking changes – every change taken is an opportunity for regression and resets some amount of the testing which has gone before.&amp;#160; So the number of bugs that are accepted towards the end of a product gets smaller and smaller. You can think of the ability to take bugs as a series of ever increasingly high barriers – it starts fairly low – just about any bug fix will be accepted into the tree.&amp;#160; This is the normal state during most of product development.&amp;#160; As time goes on and the team gets closer to shipping, the bug bar gets raised and the bugs that are considered are only those that are going to affect customers directly (as opposed to those bugs found during testing won’t necessarily be encountered by customers).&amp;#160; Then the bar gets raised again (and again, and again) until eventually it gets to the point where the only bugs that are accepted are “recall class” bugs[1].&lt;/p&gt;  &lt;p&gt;The idea behind a “recall class bug” is that it’s is a bug that is so bad that we’d be willing to call the manufacturer and pull the product off the assembly line (at a cost of millions of dollars) to fix.&amp;#160; These are the worst-of-the-worst bugs, and typically involve major scenarios not working.&amp;#160;&amp;#160; When the bug bar is at “recall class only”, there are typically only two or three bugs that are considered each day across all of Windows and even then most of the bugs brought up to the triage team aren’t accepted.&lt;/p&gt;  &lt;p&gt;At some point the bug bar gets beyond even “recall class only” – this is when you’re REALLY close to being done (typically the last two or three days of a product).&amp;#160; Normally builds of the product are done daily because there are one or two “recall class” bugs still being accepted.&amp;#160; But eventually all those bugs are fixed and the build team stops doing daily builds because there have been no changes since the previous build.&amp;#160; The test team is hard at work doing it’s final sign-off of the bits and everybody is on tenterhooks waiting for the final build to come out.&amp;#160; When you’re at this stage of the product, every once in a while a change comes in that would be really nice to have because it fixes a critical issue with an important scenario, but it’s just just not important enough to justify cracking open the bits to take the change.&amp;#160; Raymond calls these type of changes “&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2008/02/26/7897723.aspx"&gt;Remora Check-ins&lt;/a&gt;”.&amp;#160;&amp;#160; The idea is that if another bug was discovered during the final testing phase that forced us to rebuild the system, we would take these “Remora Check-ins” along for the ride.&lt;/p&gt;  &lt;p&gt;In our case, the change we made was a Remora check-in – it was an important bug, but it wasn’t important enough to justify resetting the final test pass.&amp;#160; But someone else’s component had a critical bug that HAD to be fixed and our change came along for the ride (and no, I don’t remember exactly what either of the changes were, I just know that our check-in was chronologically the last one made).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Nitpickers corner: None of the information in this post should be particularly controversial – much of what I’ve described here is software engineering 101.&amp;#160; There’s always a bar for taking bug fixes in every product – if there weren’t, you’d never ship the product (for example, the Mozilla Foundation shipped Firefox version 3.5 today (congrats!) and they still have several dozens of critical bugs active in their database – I’m sure that these are all bugs that didn’t meet their bug bar).&amp;#160; Heck, there’s even a book that’s all about &lt;a href="http://www.amazon.com/Show-Stopper-Breakneck-Generation-Microsoft/dp/0029356717"&gt;the process of shipping NT 3.1&lt;/a&gt; that covers much of this information.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;----&lt;/p&gt;  &lt;p&gt;[1] In the past these bugs would be called “Show Stoppers”.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9810114" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category></item><item><title>Everyone wants a shiny new UI</title><link>http://blogs.msdn.com/larryosterman/archive/2009/01/28/everyone-wants-a-shiny-new-ui.aspx</link><pubDate>Thu, 29 Jan 2009 08:24:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9382425</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>55</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/9382425.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=9382425</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=9382425</wfw:comment><description>&lt;p&gt;Surfing around the web, I often run into web sites that contain critiques of various aspects of Windows UI.&lt;/p&gt;  &lt;p&gt;One of the most common criticisms on those sites is &amp;quot;old style&amp;quot; dialogs.&amp;#160; In other words, dialogs that don't have the most up-to-date theming.&amp;#160; Here's an example I ran into earlier today:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/EveryonewantsashinynewUI_12D1D/AutoComplete_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="185" alt="AutoComplete" src="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/EveryonewantsashinynewUI_12D1D/AutoComplete_thumb.png" width="400" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Windows has a fair number of dialogs like this - they're often fairly old dialogs that were written before new theming elements were added (or contain animations that predate newer theming options).&amp;#160; They all work correctly but they're just ... old.&lt;/p&gt;  &lt;p&gt;Usually the web site wants the Windows team update the dialog to match the newest styling's because the dialog is &amp;quot;wrong&amp;quot;.&lt;/p&gt;  &lt;p&gt;Whenever someone asks (or more often &lt;em&gt;insists&lt;/em&gt;) that the Windows team update their particular old dialog, I sometimes want to turn around and ask them a question:&lt;/p&gt;  &lt;p&gt;&amp;quot;You get to choose: You can get this dialog fixed OR you can cut a feature from Windows, you can't get both.&amp;#160; Which feature in Windows would you cut to change this dialog?&amp;quot;&lt;/p&gt;  &lt;p&gt;Perhaps an automotive analogy would help explain my rather intemperate reaction:&lt;/p&gt;  &lt;p&gt;One of the roads near my house is a cement road and the road is starting to develop a fair number of cracks in it.&amp;#160; The folks living near the road got upset at the condition of the road and started a petition drive to get the county to repair the road.&amp;#160; Their petition worked and county came out a couple of weeks later and inspected the road and rendered their verdict on the repair (paraphrasing):&amp;#160; We've looked at the road surface and it is 60% degraded.&amp;#160; The threshold for immediate repairs on county roads is 80% degradation.&amp;#160; Your road was built 30 years ago and cement roads in this area have a 40 year expected lifespan.&amp;#160; Since the road doesn't meet our threshold for immediate repair and it hasn't met the end of its lifespan, we can't justify moving this section of road up ahead of the hundreds of other sections of road that need immediate repair.&lt;/p&gt;  &lt;p&gt;In other words, the county had a limited budget for road repairs and there were a lot of other sections of road in the county that were in a lot worse shape than the one near my house.&lt;/p&gt;  &lt;p&gt;The same thing happens in Windows - there are thousands of features in Windows and a limited number of developers who can change those features.&amp;#160;&amp;#160; Changing a dialog does not happen for free.&amp;#160; It takes time for the developers to fix UI bugs.&amp;#160; As an example, I just checked in a fix for a particularly tricky UI bug.&amp;#160; I started working on that fix in early October and it's now January.&lt;/p&gt;  &lt;p&gt;Remember, this dialog works just fine, it's just a visual inconsistency.&amp;#160; But it's going to take a developer some amount of time to fix the dialog.&amp;#160; Maybe it's only one day.&amp;#160; Maybe it's a week.&amp;#160; Maybe the fix requires coordination between multiple people (for example, changing an icon usually requires the time of both a developer AND a graphic designer).&amp;#160; That time could be spent working on fixing other bugs.&amp;#160; Every feature team goes through a triage process on incoming bugs to decide which bugs they should fix.&amp;#160; They make choices based on their limited budget (there are n developers on the team, there are m bugs to fix, each bug takes t time to fix on average, that means we need to fix (m*t)/n bugs before we can ship).&lt;/p&gt;  &lt;p&gt;Fixing theming bug like this takes time that could be spent fixing other bugs.&amp;#160; And (as I've said before) the dialog &lt;em&gt;does&lt;/em&gt; work correctly, it's just outdated.&lt;/p&gt;  &lt;p&gt;So again I come back to the question: &amp;quot;Is fixing a working but ugly dialog &lt;em&gt;really &lt;/em&gt;more important than all the other bugs?&amp;quot;&amp;#160; It's unfortunate but you have to make a choice.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt; PS: Just because we have to make choices like this doesn't mean that you shouldn't send feedback like this.&amp;#160;&amp;#160; Just like the neighbors complaining to the county about the road, it helps to let the relevant team know about the issue. Feedback like this is invaluable for the Windows team (that's what the &amp;quot;Send Feedback&amp;quot; link is there for after all).&amp;#160; Even if the team decides not to fix a particular bug in this release it doesn't mean that it won't be fixed in the next release. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9382425" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category></item><item><title>Engineering 7: A view from the bottom</title><link>http://blogs.msdn.com/larryosterman/archive/2008/10/16/engineering-7-a-view-from-the-bottom.aspx</link><pubDate>Thu, 16 Oct 2008 17:43:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9001864</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/9001864.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=9001864</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=9001864</wfw:comment><description>&lt;p&gt;About 2 months ago, Steven Sinofsky and Jon DeVaan started the “&lt;a href="http://blogs.msdn.com/e7/"&gt;Engineering Windows 7&lt;/a&gt;” blog.&amp;#160; The instant I saw the blog, I wanted to contribute to the blog (because I love writing :)).&lt;/p&gt;  &lt;p&gt;I spent a fair amount of time thinking about what to write about and realized that one thing that wasn’t likely to be discussed was how the actual &lt;em&gt;software engineering&lt;/em&gt; process of Windows 7 worked – not the data behind particular features, but how the hard core engineering work was managed.&amp;#160; So I wrote it and submitted it to Steven and Jon.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;My article (it’s too long to be considered a “post”) went &lt;a href="http://blogs.msdn.com/e7/archive/2008/10/15/engineering-7-a-view-from-the-bottom.aspx"&gt;live on the Engineering 7 blog&lt;/a&gt; sometime last night. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9001864" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category></item><item><title>Resilience is NOT necessarily a good thing</title><link>http://blogs.msdn.com/larryosterman/archive/2008/05/01/resilience-is-not-necessarily-a-good-thing.aspx</link><pubDate>Thu, 01 May 2008 19:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8447190</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>66</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/8447190.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=8447190</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=8447190</wfw:comment><description>&lt;P&gt;I just ran into &lt;A href="http://blogs.msdn.com/eric_brechner/archive/2008/05/01/crash-dummies-resilience.aspx" mce_href="http://blogs.msdn.com/eric_brechner/archive/2008/05/01/crash-dummies-resilience.aspx"&gt;this&lt;/A&gt; post by Eric Brechner who is the director of Microsoft's Engineering Excellence center.&lt;/P&gt;
&lt;P&gt;What really caught my eye was his opening paragraph:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;I heard a remark the other day that seemed stupid on the surface, but when I really thought about it I realized it was completely idiotic and irresponsible. The remark was that it's better to crash and let Watson report the error than it is to catch the exception and try to correct it.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Wow.&amp;nbsp; I'm not going to mince words: What a profoundly stupid assertion to make.&amp;nbsp; Of course it's better to crash and let the OS handle the exception than to try to continue after an exception.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have a HUGE issue with the concept that an application should catch exceptions[1] and attempt to correct them.&amp;nbsp; In my experience handling exceptions and attempting to continue is a recipe for disaster.&amp;nbsp; At best, it takes &lt;A href="http://blogs.msdn.com/larryosterman/archive/2004/09/10/228068.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2004/09/10/228068.aspx"&gt;an easily debuggable problem into one that takes hours of debugging to resolve&lt;/A&gt;.&amp;nbsp; At it's worst, exception handling can either &lt;A href="http://blogs.msdn.com/david_leblanc/archive/2007/05/10/more-on-exception-handlers.aspx" mce_href="http://blogs.msdn.com/david_leblanc/archive/2007/05/10/more-on-exception-handlers.aspx"&gt;introduce security holes&lt;/A&gt; or &lt;A href="http://blogs.msdn.com/sdl/archive/2007/04/26/lessons-learned-from-the-animated-cursor-security-bug.aspx" mce_href="http://blogs.msdn.com/sdl/archive/2007/04/26/lessons-learned-from-the-animated-cursor-security-bug.aspx"&gt;render security mitigations irrelevant&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;I have absolutely no problems with &lt;A href="http://c2.com/cgi/wiki?FailFast" mce_href="http://c2.com/cgi/wiki?FailFast"&gt;fail fast&lt;/A&gt; (which is what Eric suggests with his "Restart" option).&amp;nbsp; I think that restarting a process after the process crashes is a great idea (as long as you have a way to prevent crashes from spiraling out of control).&amp;nbsp; In Windows Vista, Microsoft built this functionality directly into the OS with the &lt;A href="http://msdn.microsoft.com/en-us/library/aa373654(vs.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa373654(vs.85).aspx"&gt;Restart Manager&lt;/A&gt;, if your application calls the &lt;A href="http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx"&gt;RegisterApplicationRestart&lt;/A&gt; API, the OS will offer to restart your application if it crashes or is non responsive.&amp;nbsp; This concept also shows up in the service restart options in the &lt;A href="http://msdn.microsoft.com/en-us/library/ms681988(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms681988(VS.85).aspx"&gt;ChangeServiceConfig2&lt;/A&gt; API (if a service crashes, the OS will restart it if you've configured the OS to restart it).&lt;/P&gt;
&lt;P&gt;I also agree with Eric's comment that asserts that cause crashes have no business living in production code, and I have no problems with asserts logging a failure and continuing (assuming that there's someone who is going to actually look at the log and can understand the contents of the log, otherwise the&amp;nbsp; logs just consume disk space).&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But I simply can't wrap my head around the idea that it's ok to catch exceptions and continue to run.&amp;nbsp; Back in the days of Windows 3.1 it might have been a good idea, but after the security fiascos of the early 2000s, any thoughts that you could continue to run after an exception has been thrown should have been removed forever.&lt;/P&gt;
&lt;P&gt;The bottom line is that when an exception is thrown, your program is in an unknown state.&amp;nbsp; Attempting to continue in that unknown state is pointless and potentially extremely dangerous - you literally have no idea what's going on in your program.&amp;nbsp; Your best bet is to let the OS exception handler dump core and hopefully your customers will submit those crash dumps to you so you can post-mortem debug the problem.&amp;nbsp; Any other attempt at continuing is a recipe for disaster.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;-------&lt;/P&gt;
&lt;P&gt;[1] To be clear: I'm not necessarily talking about C++ exceptions here, just structured exceptions.&amp;nbsp; For &lt;EM&gt;some&lt;/EM&gt; C++ and C# exceptions, it's ok to catch the exception and continue, assuming that you understand the root cause of the exception.&amp;nbsp; But if you don't know the exact cause of the exception you should never proceed.&amp;nbsp; For instance, if your binary tree class throws a "Tree Corrupt" exception, you really shouldn't continue to run, but if opening a file throws a "file not found" exception, it's likely to be ok.&amp;nbsp; For structured exceptions, I know of NO circumstance under which it is appropriate to continue running.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Edit: Cleaned up wording in the footnote.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8447190" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item><item><title>When you're analyzing the strength of a password, make sure you know what's done with it.</title><link>http://blogs.msdn.com/larryosterman/archive/2007/11/12/when-you-re-analyzing-the-strength-of-a-password-make-sure-you-know-what-s-done-with-it.aspx</link><pubDate>Tue, 13 Nov 2007 04:47:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6158666</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/6158666.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=6158666</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=6158666</wfw:comment><description>&lt;p&gt;Every once in a while, I hear someone making comments about the strength of things like long passwords.&lt;/p&gt; &lt;p&gt;For example, if you have a 255 character password that just uses the 26 roman upper and lower case letters, plus the numeric digits.&amp;nbsp; That means that your password has 62^255 possible values, if you can try a million million passwords per second, the time required would exceed the heat death of the universe.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Wow, that's cool - it means that you can never break my password if I use a long enough password. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Except...&lt;/p&gt; &lt;p&gt;The odds are very good that something in the system's going to take your password and apply a one-way hash to that password - after all, it wouldn't do to keep that password lying around in clear text where an attacker could see it.&amp;nbsp; But the instant you take a hash of a secret, the strength of the secret degrades to the strength of the hash.&lt;/p&gt; &lt;p&gt;It's another example of the &lt;a href="http://en.wikipedia.org/wiki/Pigeonhole_principle"&gt;pigeonhole principle&lt;/a&gt; in practice - if you put N+M items into N slots, you're going to have some slots with more than one entry.&amp;nbsp; The pigeonhole principle applies in this case as well.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;In other words, if the password database that holds your password uses a hash algorithm like SHA-1, your 62^255 possible character password just got reduced in strength to a 256^20 possible value hash[1]. That means that any analysis that you've done on your password doesn't matter, because all an attacker needs to do is to find a different password that hashes to the same value as your password and they've broken your password.&amp;nbsp; Since your password strength exceeds the strength of the hash code, you know that there MUST be a collision with a weaker password.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The bottom line is that when you're calculating the strength of a&amp;nbsp; password, it's important that you understand what your password looks like to an attacker.&amp;nbsp; If your password is saved as an SHA-1 or MD5 hash, that's the true maximum strength of your password.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[1]To be fair, 256^20 is something like 1.4E48, so even if you could still try a million million passwords per second, you're still looking at something like a million million years to brute force that database, but 256^20 is still far less than 62^255.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6158666" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item><item><title>Some final thoughts on Threat Modeling...</title><link>http://blogs.msdn.com/larryosterman/archive/2007/10/01/some-final-thoughts-on-threat-modeling.aspx</link><pubDate>Mon, 01 Oct 2007 19:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5225270</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/5225270.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=5225270</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=5225270</wfw:comment><description>&lt;P&gt;I want to wrap up the threat modeling posts with a summary and some comments on the entire process.&amp;nbsp; Yeah, I know I should have done this last week, but I got distracted :).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;First, a summary of the threat modeling posts:&lt;/P&gt;
&lt;P&gt;Part 1: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/08/30/threat-modeling-once-again.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/08/30/threat-modeling-once-again.aspx"&gt;Threat Modeling, Once again.&amp;nbsp; In which our narrator introduces the idea of a threat model diagram&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 2: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/08/31/threat-modeling-again-drawing-the-diagram.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/08/31/threat-modeling-again-drawing-the-diagram.aspx"&gt;Threat Modeling Again. Drawing the Diagram.&amp;nbsp; In which our narrator introduces the diagram for the PlaySound API&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 3: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/04/threat-modeling-again-stride.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/04/threat-modeling-again-stride.aspx"&gt;Threat Modeling Again, Stride.&amp;nbsp; Introducing the various STRIDE categories.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 4: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/05/threat-modeling-again-stride-mitigations.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/05/threat-modeling-again-stride-mitigations.aspx"&gt;Threat Modeling Again, Stride Mitigations.&amp;nbsp; Discussing various mitigations for the STRIDE categories.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 5: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/07/threat-modeling-again-what-does-stride-have-to-do-with-threat-modeling.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/07/threat-modeling-again-what-does-stride-have-to-do-with-threat-modeling.aspx"&gt;Threat Modeling Again, What does STRIDE have to do with threat modeling?&amp;nbsp; The relationship between STRIDE and diagram elements.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 6: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/10/threat-modeling-again-stride-per-element.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/10/threat-modeling-again-stride-per-element.aspx"&gt;Threat Modeling Again, STRIDE per Element.&amp;nbsp; In which the concept of STRIDE/Element is discussed.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 7: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/11/threat-modeling-again-threat-modeling-playsound.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/11/threat-modeling-again-threat-modeling-playsound.aspx"&gt;Threat Modeling Again, Threat Modeling PlaySound.&amp;nbsp; Which enumerates the threats against the PlaySound API.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 8: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/13/threat-modeling-again-analyzing-the-threats-to-playsound.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/13/threat-modeling-again-analyzing-the-threats-to-playsound.aspx"&gt;Threat Modeling Again, Analyzing the threats to PlaySound.&amp;nbsp; In which the threat modeling analysis work against the threats to PlaySound is performed.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 9: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/14/threat-modeling-again-pulling-the-threat-model-together.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/14/threat-modeling-again-pulling-the-threat-model-together.aspx"&gt;Threat Modeling Again, Pulling the threat model together.&amp;nbsp; Which describes the narrative structure of a threat model.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 10: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/17/threat-modeling-again-presenting-the-playsound-threat-model.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/17/threat-modeling-again-presenting-the-playsound-threat-model.aspx"&gt;Threat Modeling Again, Presenting the PlaySound threat model.&amp;nbsp; Which doesn't need a pithy summary, because the title describes what it is.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 11: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/18/threat-modeling-again-threat-modeling-in-practice.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/18/threat-modeling-again-threat-modeling-in-practice.aspx"&gt;Threat Modeling Again, Threat Modeling in Practice.&amp;nbsp; Presenting the threat model diagrams for a real-world security problem .&lt;/A&gt;[1]&lt;/P&gt;
&lt;P&gt;Part 12: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/19/threat-modeling-again-threat-modeling-and-the-firefoxurl-issue.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/19/threat-modeling-again-threat-modeling-and-the-firefoxurl-issue.aspx"&gt;Threat Modeling Again, Threat Modeling and the firefoxurl issue. Analyzing the real-world problem from the standpoint of threat modeling.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Part 13: &lt;A href="http://blogs.msdn.com/larryosterman/archive/2007/09/21/threat-modeling-again-threat-modeling-rules-of-thumb.aspx" mce_href="http://blogs.msdn.com/larryosterman/archive/2007/09/21/threat-modeling-again-threat-modeling-rules-of-thumb.aspx"&gt;Threat Modeling Again, Threat Modeling Rules of Thumb.&amp;nbsp; A document with some useful rules of thumb to consider when threat modeling.&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Remember that threat modeling is an analysis&amp;nbsp;tool. You threat model to identify threats to your component, which then lets you know where you need to concentrate your resources.&amp;nbsp; Maybe you need to encrypt a particular data channel to protect it from snooping.&amp;nbsp; Maybe you need to change the ACLs on a data store to ensure that an attacker can't modify the contents of the store.&amp;nbsp; Maybe you just need to carefully validate the contents of the store before you read it.&amp;nbsp; The threat modeling process tells you where to look and gives you suggestions about what to look for, but it doesn't solve the problem.&amp;nbsp; It might be that the only thing that comes out from your threat modeling process is a document that says "We don't care about any of the threats to this component".&amp;nbsp; That's ok, at a minimum, it means that you considered the threats and decided that they were acceptable.&lt;/P&gt;
&lt;P&gt;The threat modeling process is also a living process. I'm 100% certain that 2 years from now, we're going to be doing threat modeling differently from the way that we do it today.&amp;nbsp; Experience has shown that every time we apply threat modeling to a product, we realize new things about the process of performing threat modeling, and find new, more efficient ways of going about the process.&amp;nbsp;&amp;nbsp; Even now, the various teams involved with threat modeling in my division have proposed new changes the process based on the experiences of our current round of threat modeling.&amp;nbsp; Some of them will be adopted as best practices across Microsoft, some of them will be dropped on the floor.&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;What I've described over these posts is the process of threat modeling as it's done today in the Windows division at Microsoft.&amp;nbsp; Other divisions use threat modeling differently - the threat landscape for Windows is different from the threat landscape for SQL Server and Exchange, which is different from the threat landscape for the various Live products, and it's entirely different for our internal IT processes.&amp;nbsp; All of these groups use threat modeling, and they use the core mechanisms in similar ways, but because each group that does threat modeling has different threats and different risks, the process plays out differently for each team.&lt;/P&gt;
&lt;P&gt;If your team decides to adopt threat modeling, you need to consider how it applies to your components and adopt the process accordingly.&amp;nbsp; Threat Modeling is absolutely not a one-size-fits-all process, but it IS an invaluable tool.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;EDIT TO ADD: Adam Shostak on the Threat Modeling Team at Microsoft pointed out that the threat modeling team has a developer position open.&amp;nbsp; You can find more information about the position by going to here:&amp;nbsp;&lt;SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="http://members.microsoft.com/careers/search/default.aspx"&gt;&lt;FONT color=#0000ff&gt;http://members.microsoft.com/careers/search/default.aspx&lt;/FONT&gt;&lt;/A&gt;&amp;nbsp;and searching for job #&lt;SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;207443.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;[1] Someone posting a &lt;A href="http://www.schneier.com/blog/archives/2007/10/threat_modeling.html#c205686" mce_href="http://www.schneier.com/blog/archives/2007/10/threat_modeling.html#c205686"&gt;comment on Bruce Schneier's blog&lt;/A&gt;&amp;nbsp;took me for task for using a browser vulnerability.&amp;nbsp; I chose that particular vulnerability because it was&amp;nbsp;the first that came to mind.&amp;nbsp; I could have just as easily picked the DMG loading logic in OSX or the .ANI file code in Windows for examples (actually the DMG file issues are&amp;nbsp;in several ways far more interesting than the firefoxurl issue&amp;nbsp;- the .ANI file issue is actually relatively boring from a threat modeling standpoint).&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5225270" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item><item><title>What's wrong with this code, part 21 - A Psychic Debugging Example - The answers.</title><link>http://blogs.msdn.com/larryosterman/archive/2007/09/26/what-s-wrong-with-this-code-part-21-a-psychic-debugging-example-the-answers.aspx</link><pubDate>Wed, 26 Sep 2007 23:17:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5151067</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/5151067.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=5151067</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=5151067</wfw:comment><description>&lt;p&gt;So for the past &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/24/what-s-wrong-with-this-code-part-21-a-psychic-debugging-example.aspx"&gt;couple&lt;/a&gt; of &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/25/what-s-wrong-with-this-code-part-21-a-psychic-debugging-example-the-missing-piece.aspx"&gt;posts&lt;/a&gt;, I've been walking through a psychic debugging experience I had over the weekend.&lt;/p&gt; &lt;p&gt;As I presented the problem, there were three pieces of information needed to debug the problem.&lt;/p&gt; &lt;p&gt;An interface:&lt;/p&gt;&lt;code&gt; &lt;blockquote&gt; &lt;p&gt;class IPsychicInterface &lt;br&gt;{&lt;br&gt;public:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual bool DoSomeOperation(int argc, _TCHAR *argv[]) = 0;&lt;br&gt;}; &lt;/p&gt;&lt;/blockquote&gt;&lt;/code&gt; &lt;p&gt;A test application:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;code&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; register int value1 = 1;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IPsychicInterface *psychicInterface = GetPsychicInterface();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; register int value2 = 2; &lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; psychicInterface-&amp;gt;DoSomeOperation(argc, argv);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert(value1 == 1);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert(value2 == 2);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br&gt;}&lt;/p&gt;&lt;/blockquote&gt;&lt;/code&gt; &lt;p&gt;and some assembly language code:&lt;/p&gt; &lt;blockquote&gt;&lt;code&gt; &lt;p&gt;0040106B&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edi&amp;nbsp; &lt;br&gt;0040106C&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx&amp;nbsp; &lt;br&gt;0040106D&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; al,1 &lt;br&gt;0040106F&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esi&amp;nbsp; &lt;br&gt;00401070&amp;nbsp; ret&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0Ch&amp;nbsp; &lt;/p&gt;&lt;/code&gt;&lt;/blockquote&gt; &lt;p&gt;As I mentioned in my last post, the problem was tracked down to a stack imbalance when calling the DoSomeOperation method, and when I saw the postamble for DoSomeOperation, I quickly realized the answer to the problem.&lt;/p&gt; &lt;p&gt;There are essentially 4 &lt;a href="http://msdn2.microsoft.com/en-us/library/984x0h58(VS.71).aspx"&gt;separate calling conventions&lt;/a&gt; supported by Microsoft's compilers - it turns out that you can figure out several of them from just looking at the code.&amp;nbsp; For the &lt;a href="http://msdn2.microsoft.com/en-us/library/zxk0tw93(VS.71).aspx"&gt;stdcall&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/ek8tkfbw(VS.71).aspx"&gt;thiscall&lt;/a&gt; calling conventions, input parameters are passed onto the routine, and the callee is responsible for cleaning up the stack (this contrasts with the &lt;a href="http://msdn2.microsoft.com/en-us/library/zkwh89ks(VS.71).aspx"&gt;cdecl&lt;/a&gt; calling convention where the caller is responsible for cleaning the stack).&amp;nbsp; From the postamble, we know that this function is either a stdcall or a thiscall function, since the "ret" instruction adjusts the stack.&lt;/p&gt; &lt;p&gt;I've already stated that this is x86 code, and the RET 0CH indicates that the routine pops off 12 bytes of values off the stack.&amp;nbsp; This is clearly a problem, because the DoSomeOperation routine only takes two parameters (which would take 8 bytes). The RET 0CH implies that the implementation of DoSomeOperation took 3 parameters!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This implies that we're dealing with a violation of the one definition rule (ODR).&amp;nbsp; The One Definition Rule is a part of the C++ standard (section 3.2) which states: "No translation unit shall contain more than one definition of any variable, function, class type, enumeration type or template.".&amp;nbsp; In other words, when you declare a function in separate object files, you need to make sure that they all use the same definitions of structures.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Most commonly ODR violations this show up when you change a header file but don't rebuild all the source files that depend on that file - there's a ton of work that's been done to automatically manage dependencies to avoid this particular issue.&lt;/p&gt; &lt;p&gt;And if you look at the source code for the PsychicInterface logic, you'll see the problem immediately:&lt;/p&gt; &lt;blockquote&gt;&lt;code&gt; &lt;p&gt;class IPsychicInterface &lt;br&gt;{&lt;br&gt;public:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual bool DoSomeOperation(int argc, _TCHAR *argv[], _TCHAR *envp[]) = 0;&lt;br&gt;};&lt;br&gt; &lt;p&gt;bool CPsychicInterface::DoSomeOperation(int argc, _TCHAR *argv[], _TCHAR *envp[])&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int count = argc;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (count--)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("%S", argv[count]);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br&gt;}&lt;/p&gt;&lt;/code&gt;&lt;/blockquote&gt; &lt;p&gt;The PsychicInterface code has it's own private definition of IPsychicInterface which doesn't match the definition in the test application.&lt;/p&gt; &lt;p&gt;Obviously this is an utterly contrived example.&amp;nbsp; The real problem was much more complicated than this - the violation was in an export from a DLL, and involved external components, which made this more complicated.&amp;nbsp; In many ways, it was similar to the problem that Raymond talked about &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2004/01/15/58973.aspx"&gt;here&lt;/a&gt;&amp;nbsp;(except in this case, we're in a position to fix the code involved).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5151067" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Things+you+shouldn_2700_t+do_2E00_/default.aspx">Things you shouldn't do.</category></item><item><title>What's wrong with this code, Part 21 - A psychic debugging example: The missing piece</title><link>http://blogs.msdn.com/larryosterman/archive/2007/09/25/what-s-wrong-with-this-code-part-21-a-psychic-debugging-example-the-missing-piece.aspx</link><pubDate>Tue, 25 Sep 2007 19:39:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5124301</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>18</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/5124301.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=5124301</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=5124301</wfw:comment><description>&lt;p&gt;As I mentioned &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/24/what-s-wrong-with-this-code-part-21-a-psychic-debugging-example.aspx"&gt;yesterday&lt;/a&gt;, one of the other developers in my group had hit a sticky problem, and he asked me for my opinion on what was going wrong.&lt;/p&gt; &lt;p&gt;There were 3 pieces of information that I needed to use to diagnose the problem, I gave you two of them yesterday:&lt;/p&gt; &lt;p&gt;The interface:&lt;/p&gt; &lt;p&gt;&lt;code&gt; &lt;blockquote&gt; &lt;p&gt;class IPsychicInterface &lt;br&gt;{&lt;br&gt;public:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual bool DoSomeOperation(int argc, _TCHAR *argv[]) = 0;&lt;br&gt;}; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;/code&gt; &lt;p&gt;And the test application:  &lt;blockquote&gt; &lt;p&gt;&lt;code&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; register int value1 = 1;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IPsychicInterface *psychicInterface = GetPsychicInterface();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; register int value2 = 2; &lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; psychicInterface-&amp;gt;DoSomeOperation(argc, argv);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert(value1 == 1);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert(value2 == 2);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br&gt;}&lt;/p&gt;&lt;/blockquote&gt;&lt;/code&gt; &lt;p&gt;Originally the problem was that the ESI register was being trashed.&amp;nbsp; Since the C and C++ calling convention requires that the ESI register be preserved and the ESI register was trashed, that narrowed down the failure to three possible causes to the problem:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Somewhere inside DoSomeOperation, there was a stack overflow that caused the saved version of ESI to be corrupted.&amp;nbsp; This was actually my first thought.&lt;/li&gt; &lt;li&gt;Somewhere inside DoSomeOperation, there was a stack imbalance, which would cause garbage to be restored when the ESI register was popped off the stack.&amp;nbsp; Normally the compiler catches these errors, so I originally discounted this possibility.&lt;/li&gt; &lt;li&gt;There was a horrible compiler bug or OS bug which caused the register to be trashed (which is extraordinarily unlikely (but &lt;em&gt;has&lt;/em&gt; happened)).&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The other developer had chased the problem down further and realized that there was a stack imbalance on the call to DoSomeOperation.&amp;nbsp; There are basically two things that can cause a stack imbalance, most of the people who left comments in the &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/24/what-s-wrong-with-this-code-part-21-a-psychic-debugging-example.aspx"&gt;original post&lt;/a&gt;&amp;nbsp;caught one of them, some caught the other:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A calling convention mismatch.&lt;/li&gt; &lt;li&gt;A parameter declaration mismatch.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;But I didn't have enough information to figure out which of the two it was.&amp;nbsp; That's when he gave me the final piece that let me accurately figure out what was going wrong.&lt;/p&gt; &lt;p&gt;The final piece was the last bit of assembly language in the DoSomeOperation function:&lt;/p&gt;&lt;code&gt; &lt;blockquote&gt; &lt;p&gt;0040106B&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edi&amp;nbsp; &lt;br&gt;0040106C&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx&amp;nbsp; &lt;br&gt;0040106D&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; al,1 &lt;br&gt;0040106F&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esi&amp;nbsp; &lt;br&gt;00401070&amp;nbsp; ret&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0Ch&amp;nbsp; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;/code&gt;Now that you have the last piece, what was the bug?&amp;nbsp; Be specific - we already know that the problem is a stack imbalance, but what's the root cause?&lt;/p&gt; &lt;p&gt;For a bonus, why didn't the compiler catch it?&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5124301" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Things+you+shouldn_2700_t+do_2E00_/default.aspx">Things you shouldn't do.</category></item><item><title>Threat Modeling Again, Threat Modeling Rules of Thumb</title><link>http://blogs.msdn.com/larryosterman/archive/2007/09/21/threat-modeling-again-threat-modeling-rules-of-thumb.aspx</link><pubDate>Fri, 21 Sep 2007 20:20:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5036111</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/5036111.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=5036111</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=5036111</wfw:comment><description>&lt;p&gt;I wrote this piece up for our group as we entered the most recent round of threat models.&amp;nbsp; I've cleaned it up a bit (removing some Microsoft-specific stuff), and there's stuff that's been talked about before, but the rest of the document is pretty relevant.&amp;nbsp;  &lt;p&gt;&amp;nbsp;  &lt;p&gt;---------------------------------------  &lt;p&gt;As you go about filling in the threat model threat list, it’s important to consider the consequences of entering threats and mitigations.&amp;nbsp; While it can be easy to find threats, it is important to realize that all threats have real-world consequences for the development team.  &lt;p&gt;At the end of the day, this process is about ensuring that our customer’s machines aren’t compromised. When we’re deciding which threats need mitigation, we concentrate our efforts on those where the attacker can cause real damage. &lt;/p&gt; &lt;p&gt;&amp;nbsp; &lt;p&gt;When we’re threat modeling, we should ensure that we’ve identified as many of the potential threats as possible (even if you think they’re trivial). At a minimum, the threats we list that we chose to ignore will remain in the document to provide guidance for the future.&amp;nbsp;  &lt;p&gt;&amp;nbsp; &lt;p&gt;Remember that the feature team can always decide that we’re ok with accepting the risk of a particular threat (subject to the SDL security review process). But we want to make sure that we mitigate the right issues.  &lt;p&gt;To help you guide your thinking about what kinds of threats deserve mitigation, here are some rules of thumb that you can use while performing your threat modeling.  &lt;p&gt;1. If the data hasn’t crossed a trust boundary, you don’t really care about it.  &lt;p&gt;2. If the threat requires that the attacker is ALREADY running code on the client at your privilege level, you don’t really care about it.  &lt;p&gt;3. If your code runs with any elevated privileges (even if your code runs in a restricted svchost instance) you need to be concerned.  &lt;p&gt;4. If your code invalidates assumptions made by other entities, you need to be concerned.  &lt;p&gt;5. If your code listens on the network, you need to be concerned.  &lt;p&gt;6. If your code retrieves information from the internet, you need to be concerned.  &lt;p&gt;7. If your code deals with data that came from a file, you need to be concerned (these last two are the inverses of rule #1).  &lt;p&gt;8. If your code is marked as safe for scripting or safe for initialization, you need to be REALLY concerned.  &lt;p&gt;&amp;nbsp;  &lt;p&gt;Let’s take each of these in turn, because there are some subtle distinctions that need to be called out.  &lt;h2&gt;If the data hasn’t crossed a trust boundary, you don’t really care about it.&lt;/h2&gt; &lt;p&gt;For example, consider the case where a hostile application passes bogus parameters into our API. In that case, the hostile application lives within the same trust boundary as the application, so you can simply certify the threat. The same thing applies to window messages that you receive. In general, it’s not useful to enumerate threats within a trust boundary. [Editors Note: Yesterday, &lt;a href="http://blogs.msdn.com/david_leblanc/archive/2007/09/19/threat-modeling-the-bold-button-is-boring.aspx"&gt;David LeBlanc wrote an article about this very issue&lt;/a&gt;&amp;nbsp;- I 100% agree with what he says there.]&amp;nbsp;  &lt;p&gt;But there’s a caveat (of course there’s a caveat, there’s ALWAYS a caveat). Just because your threat model diagram doesn't have a trust boundary on it, it doesn't mean that the data being validated hasn't crossed a trust boundary on the way to your code.  &lt;p&gt;Consider the case of an application that takes a file name from the network and passes that filename into your API. And further consider the case where your API has an input validation bug that causes a buffer overflow. In that case, it’s YOUR responsibility to fix the buffer overflow – an attacker can use the innocent application to exploit your code. Before you dismiss this issue as being unlikely, consider &lt;a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-3670"&gt;CVE-2007-3670&lt;/a&gt;. The Firefox web browser allows the user to execute scripts passed in on the command line, and registered a URI handler named “firefoxurl” with the OS with the start action being “firefox.exe %1” (this is a simplification). The attacker simply included a “firefoxurl:&amp;lt;javascript&amp;gt;” in a URL and was able to successfully take ownership of the client machine. In this case, the firefox browser assumed that there was no trust boundary between firefox.exe and the invoker, but it didn’t realize that it introduced such a trust boundary when it created the “firefoxurl” URI handler.  &lt;h2&gt;If the threat requires that the attacker is ALREADY running code on the client at your privilege level, you don’t really care about it.&lt;/h2&gt; &lt;p&gt;For example, consider the case where a hostile application writes values into a registry key that’s read by your component. Writing those keys requires that there be some application currently running code on the client, which requires that the bad guy first be able to get code to run on the client box.  &lt;p&gt;While the threats associated with this are real, it’s not that big a problem and you can probably state that you aren’t concerned by those threats because they require that the bad guy run code on the box (see &lt;a href="http://www.microsoft.com/technet/archive/community/columns/security/essays/10imlaws.mspx?mfr=true"&gt;Immutable Law&lt;/a&gt; #1: “&lt;a href="http://www.microsoft.com/technet/archive/community/columns/security/essays/10imlaws.mspx#EBB"&gt;If a bad guy can persuade you to run his program on your computer, it’s not your computer anymore&lt;/a&gt;”).  &lt;p&gt;Please note that this item has a HUGE caveat: it ONLY applies if the attacker’s code is running at the same privilege level as your code. If that’s not the case, you have the next rule of thumb:  &lt;h2&gt;If your code runs with any elevated privileges, you need to be concerned.&lt;/h2&gt; &lt;p&gt;We DO care about threats that cross privilege boundaries. That means that any data communication between an application and a service (which could be an RPC, it could be a registry value, it could be a shared memory region) must be included in the threat model.  &lt;p&gt;Even if you’re running in a low privilege service account, you still may be attacked – one of the privileges that all services get is the SE_IMPERSONATE_NAME privilege. This is actually one of the more dangerous privileges on the system because it can allow a patient attacker to take over the entire box. Ken “Skywing” Johnson wrote about this in a couple of posts on his blog (&lt;a href="http://www.nynaeve.net/?p=154"&gt;1&lt;/a&gt; and &lt;a href="http://www.nynaeve.net/?p=155"&gt;2&lt;/a&gt;) on his excellent blog Nynaeve. David LeBlanc has a subtly different take on this issue (see &lt;a href="http://blogs.msdn.com/david_leblanc/archive/2007/03/25/impersonation-isn-t-dangerous.aspx"&gt;here&lt;/a&gt;), but the reality is that both David and Ken agree more than they disagree on this issue. If your code runs as a service, you MUST assume that you’re running with elevated privileges. This applies to all data read – rule #2 (requiring an attacker to run code) does not apply when you cross privilege levels, because the attacker could be writing code under a low privilege account to enable an elevation of privilege attack.  &lt;p&gt;In addition, if your component has a use scenario that involves running the component elevated, you also need to consider that in your threat modeling.  &lt;h2&gt;If your code invalidates assumptions made by other entities, you need to be concerned&lt;/h2&gt; &lt;p&gt;The reason that the firefoxurl problem listed above was such a big deal was that the firefoxurl handler invalidated some of the assumptions made by the other components of Firefox. When the Firefox team threat modeled firefox, they made the assumption that Firefox would only be invoked in the context of the user.&amp;nbsp; As such it was totally reasonable to&amp;nbsp;add support for executing scripts passed in on the command line (see rule of thumb #1).&amp;nbsp; However, when they threat modeled the firefoxurl: URI handler implementation, they didn’t consider that they had now introduced a trust boundary between the invoker of Firefox and the Firefox executable.&amp;nbsp;&amp;nbsp;  &lt;p&gt;So you need to be aware of the assumptions of all of your related components and ensure that you’re not changing those assumptions. If you are, you need to ensure that your change doesn’t introduce issues.  &lt;h2&gt;If your code retrieves information from the internet, you need to be concerned&lt;/h2&gt; &lt;p&gt;The internet is a totally untrusted resource (no duh). But this has profound consequences when threat modeling. All data received from the Internet MUST be treated as totally untrusted and must be subject to strict validation.  &lt;h2&gt;If your code deals with data that came from a file, then you need to be concerned.&lt;/h2&gt; &lt;p&gt;In the previous section, I talked about data received over the internet. Microsoft has issued several bulletins this year that required an attacker tricking a user into downloading a specially crafted file over the internet; as a consequence, ANY file data must be treated as potentially malicious. For example, &lt;a href="http://go.microsoft.com/fwlink/?LinkId=88628"&gt;MS07-047&lt;/a&gt; (a vulnerability in WMP) required that the attacker force the user to view a specially crafted WMP skin. &lt;b&gt;The consequence of this is that that ANY file parsed by our code MUST be treated as coming from a lower level of trust.&lt;/b&gt;  &lt;p&gt;Every single file parser MUST treat its input as totally untrusted –MS07-047 is only one example of an MSRC vulnerability, there have been others. Any code that reads data from a file MUST validate the contents. It also means that we need to work to ensure that we have fuzzing in place to validate our mitigations.  &lt;p&gt;And the problem goes beyond file parsers directly. Any data that can possibly be read from a file cannot be trusted. &amp;lt;A senior developer in our division&amp;gt; brings up the example of a&amp;nbsp;codec as a perfect example. The file parser parses the container and determines that the container isn't corrupted. It then extracts the format information and finds the appropriate codec for that format. The parser then loads the codec and hands the format information and file data to the codec.  &lt;p&gt;The only thing that the codec knows is that the format information that’s been passed in is valid. That’s it. Beyond the fact that the format information is of an appropriate size and has a verifiable type, the codec can make no assumptions about the contents of the format information, and it can make no assumptions about the file data. Even though the codec doesn’t explicitly parse the file, it’s still dealing with untrusted data read from the file.  &lt;h2&gt;If your code is marked as “Safe For Scripting” or “Safe for Initialization”, you need to be REALLY concerned.&lt;/h2&gt; &lt;p&gt;If your code is marked as “Safe For Scripting” (or if your code can be invoked from a control that is marked as Safe For Scripting), it means that your code can be executed in the context of a web browser, and that in turn means that the bad guys are going to go after your code. There have been way too many MSRC bulletins about issues with ActiveX controls.  &lt;p&gt;Please note that some of the issues with ActiveX controls can be quite subtle. For instance, in &lt;a href="http://support.microsoft.com/kb/321678"&gt;MS02-032&lt;/a&gt; we had to issue an MSRC fix because one of the APIs exposed by the WMP OCX returned a different error code if a path passed into the API was a file or if it was a directory – that constituted an Information Disclosure vulnerability and an attacker could use it to map out the contents of the users hard disk.  &lt;h2&gt;In conclusion&lt;/h2&gt; &lt;p&gt;Vista raised the security bar for attackers significantly. As Vista adoption spreads, attackers will be forced to find new ways to exploit our code. That means that it’s more and more important to ensure that we do a good job ensuring that they have as few opportunities as possible to make life difficult for our customers.&amp;nbsp; The threat modeling process helps us understand the risks associated with our features and understand where we need to look for potential issues.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5036111" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item><item><title>Threat Modeling Again, Threat modeling and the fIrefoxurl issue.</title><link>http://blogs.msdn.com/larryosterman/archive/2007/09/19/threat-modeling-again-threat-modeling-and-the-firefoxurl-issue.aspx</link><pubDate>Wed, 19 Sep 2007 20:33:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4999101</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>26</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/4999101.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=4999101</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=4999101</wfw:comment><description>&lt;p&gt;Yesterday I presented my version of the diagrams for Firefox's command line handler and the IE/URLMON's URL handler.&amp;nbsp; To refresh, here they are again:&lt;/p&gt; &lt;p&gt;&amp;nbsp;Here's my version of Firefox's diagram:&lt;/p&gt; &lt;p&gt;&lt;img src="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/ThreatModelingAgainThreatModelinginPract_C010/image.png"&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;And my version of IE/URLMON's URL handler diagram:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img src="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/ThreatModelingAgainThreatModelinginPract_C010/image_2.png"&gt;&lt;/p&gt; &lt;p&gt;As &lt;/img&gt;&amp;nbsp;I mentioned yesterday, even though there's a trust boundary between the user and Firefox, my interpretation of the original design for the Firefox command line parsing says that this is an acceptable risk[1], since there is nothing that the user can specify via the chrome engine that they can't do from the command line.&amp;nbsp; In the threat model for the Firefox command line parsing, this assumption should be called out, since it's important.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Now let's think about what happens when you add in the firefoxurl URL handler to the mix?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;For that, you need to go to the IE/URLMON diagram.&amp;nbsp; There's a clear trust boundary between the web page and IE/URLMON.&amp;nbsp; That trust boundary applies to all of the data passed in via the URL, and all of the data should be considered "tainted".&amp;nbsp; If your URL handler is registered using the "shell" key, then IE passes the URL to the shell, which launches the program listed in the "command" verb replacing the %1 value in the command verb with the URL specified (see &lt;a href="http://msdn2.microsoft.com/en-us/library/aa767914.aspx"&gt;this&lt;/a&gt;&amp;nbsp;for more info)[2].&amp;nbsp; If, on the other hand, you've registered an &lt;a href="http://msdn2.microsoft.com/en-us/library/aa767916.aspx"&gt;asynchronous protocol handler&lt;/a&gt;, then IE/URLMON will instantiate your COM object and will give you the ability to validate the incoming URL and to change how IE/URLMON treats the URL.&amp;nbsp; Jesper discusses this in his post "&lt;a href="http://msinfluentials.com/blogs/jesper/archive/2007/07/10/blocking-the-firefox-gt-ie-0-day.aspx"&gt;Blocking the FIrefox&lt;/a&gt;".&lt;/p&gt; &lt;p&gt;The key thing to consider is that if you use the "shell" registration mechanism (which is significantly easier than using the asynchronous protocol handler mechanism), IE/URLMON is going to pass that tainted data to your application on the command line.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Since the firefoxurl URL handler used the "shell" registration mechanism, it means that the URL from the internet is going to be passed to Firefox's command line handler.&amp;nbsp; But this violates the assumption that the Firefox command line handler made - they assume that their command line was authored with the same level of trust as the user invoking firefox.&amp;nbsp; And that's a problem, because now you have a mechanism for any internet site to execute code on the browser client with the privileges of the user.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;How would a complete threat model have shown that there was an issue?&amp;nbsp; The Firefox command line threat model showed that there was a potential issue, and the threat analysis of that potential issue showed that the threat was an accepted risk.&lt;/p&gt; &lt;p&gt;When the firefoxurl feature was added, the threat model analysis of that feature should have looked similar to the IE/URLMON threat model I called out above - IE/URLMON took the URL from the internet, passed it through the shell and handed it to Firefox (URL Handler above).&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So how would threat modeling have helped to find the bug?&lt;/p&gt; &lt;p&gt;There are two possible things that could have happened next.&amp;nbsp; When the firefoxurl handler team[3] analyzed their threat model, they would have realized that they were passing high risk data (all data from the internet should be treated as untrusted) to the command line of the Firefox application.&amp;nbsp; That should have immediately raised red flags because of the risk associated with the data.&lt;/p&gt; &lt;p&gt;At this point in their analysis, the foxurl handler team needed to confirm that their behavior was safe, which they could do either by asking someone on the Firefox command line handling team or by consulting the Firefox command line handling threat model (or both).&amp;nbsp; At that point, they would have discovered the important assumption I mentioned above, and they would have realized that they had a problem that needed to be mitigated (the actual form of the mitigation doesn't matter - I believe that the Firefox command line handling team removed their assumption, but I honestly don't know (and it doesn't matter for the purposes of this discussion)).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;As I mentioned in &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/18/threat-modeling-again-threat-modeling-in-practice.aspx"&gt;my previous post&lt;/a&gt;, I love this example because it dramatically&amp;nbsp;shows how threat modeling can help solve real world security issues. &lt;/p&gt; &lt;p&gt;I don't believe that anything in my analysis above is contrived - the issues I called out above directly follow from the threat modeling process I've outlined in the earlier posts.&amp;nbsp; &lt;/p&gt; &lt;p&gt;I've been involved in the threat modeling process here at Microsoft for quite some time now, and I've seen the threat model analysis process find this kind of issue again and again.&amp;nbsp; The threat model either exposes areas where a team needs to be concerned about their inputs or it forces teams to ask questions about their assumptions, which in turn exposes potential issues like this one (or confirms that in fact there is no issue that needs to be mitigated).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Next: Threat Modeling Rules of thumb.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;[1] Obviously, I'm not a contributor to Firefox and as such any and all of my comments about Firefox's design and architecture are at best informed guesses.&amp;nbsp; I'd love it if someone who works on Firefox or has contributed to the security analysis of Firefox would correct any mistakes I'm making here.&lt;/p&gt; &lt;p&gt;[2] Apparently IE/URLMON doesn't &lt;a href="http://www.faqs.org/rfcs/rfc1738"&gt;URLEncode&lt;/a&gt; the string that it hands to the URL handler - I don't know why it does that (probably for compatibility reasons), but that isn't actually relevant to this discussion (especially since all versions of Firefox before 2.0.0.6, &lt;a href="http://www.mozilla.org/security/announce/2007/mfsa2007-27.html"&gt;seem to have had&amp;nbsp;the same behavior as IE&lt;/a&gt;).&amp;nbsp; Even if IE had URL encoded the URL before handing it to the handler, Firefox is still being handed untrusted input which violates a critical assumption made by the Firefox command line handler developers.&lt;/p&gt; &lt;p&gt;[3] Btw, I'm using the term "team" loosely.&amp;nbsp; It's entirely possible that the same one individual did both the Firefox command line handling work AND the firefoxurl protocol handler - it doesn't actually matter.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4999101" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item><item><title>Threat Modeling Again, Threat Modeling in Practice</title><link>http://blogs.msdn.com/larryosterman/archive/2007/09/18/threat-modeling-again-threat-modeling-in-practice.aspx</link><pubDate>Wed, 19 Sep 2007 01:48:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4987437</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/4987437.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=4987437</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=4987437</wfw:comment><description>&lt;p&gt;I've been &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/08/30/threat-modeling-once-again.aspx"&gt;writing&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/08/31/threat-modeling-again-drawing-the-diagram.aspx"&gt;a&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/04/threat-modeling-again-stride.aspx"&gt;LOT&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/05/threat-modeling-again-stride-mitigations.aspx"&gt;about&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/07/threat-modeling-again-what-does-stride-have-to-do-with-threat-modeling.aspx"&gt;threat&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/10/threat-modeling-again-stride-per-element.aspx"&gt;modeling&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/11/threat-modeling-again-threat-modeling-playsound.aspx"&gt;recently&lt;/a&gt;&amp;nbsp;&lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/13/threat-modeling-again-analyzing-the-threats-to-playsound.aspx"&gt;but&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/14/threat-modeling-again-pulling-the-threat-model-together.aspx"&gt;one&lt;/a&gt; &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/09/17/threat-modeling-again-presenting-the-playsound-threat-model.aspx"&gt;of&lt;/a&gt; the things I haven't talked about is the practical value of the threat modeling process.&lt;/p&gt; &lt;p&gt;Here at Microsoft, we've totally drunk the threat modeling cool-aid.&amp;nbsp; One of &lt;a href="http://www.emergentchaos.com"&gt;Adam Shostak's&lt;/a&gt; papers on threat modeling has the following quote from &lt;a href="http://blogs.msdn.com/michael_howard"&gt;Michael Howard&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;"If we had our hands tied behind our backs (we don't) and could do only one thing to improve software security... we would do threat modeling every day of the week."&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I want to talk about a real-world example of a security problem where threat modeling would have hopefully avoided a potential problem.&lt;/p&gt; &lt;p&gt;I happen to love this problem, because it does a really good job of showing how the evolution of complicated systems can introduce unexpected security problems.&amp;nbsp; The particular issue I'm talking about is known as &lt;a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-3670"&gt;CVE-2007-3670&lt;/a&gt;.&amp;nbsp; I seriously recommend people go to the CVE site and read the references to the problem, they provide a excellent background on the problem. &lt;/p&gt; &lt;p&gt;CVE-2007-3670 describes a vulnerability in the Mozilla Firefox browser that uses Internet Explorer as an exploit vector. There's been a TON written about this particular issue (see the references on the CVE page for most of the discussion), I don't want to go into the pros and cons of whether or not this is an IE or a FireFox bug.&amp;nbsp; I only want to discuss this particular issue from a threat modeling standpoint.&lt;/p&gt; &lt;p&gt;There are four components involved in this vulnerability, each with their own threat model:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The Firefox browser.&lt;/li&gt; &lt;li&gt;Internet Explorer.&lt;/li&gt; &lt;li&gt;The "firefoxurl:" URI registration.&lt;/li&gt; &lt;li&gt;The Windows Shell (explorer).&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Each of the components in question play a part in the vulnerability.&amp;nbsp; Let's take them in turn.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The Firefox browser provides a &lt;a href="http://kb.mozillazine.org/Command_line_arguments"&gt;command line argument&lt;/a&gt;&amp;nbsp;"-chrome" which allows you to load the chrome specified at a particular location.&lt;/li&gt; &lt;li&gt;Internet Explorer provides an &lt;a href="http://msdn2.microsoft.com/en-us/library/aa767914.aspx"&gt;extensibility mechanism which allows 3rd parties to register specific URI handlers&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;The "firefoxurl:" URL registration, which uses the simplest form of URL handler registration which simply instructs the shell to execute "&amp;lt;firefoxpath&amp;gt;\firefox.exe -url "%1" -requestPending".&amp;nbsp; Apparently this was added to Firefox to allow web site authors to force the user to use Firefox when viewing a link.&amp;nbsp; I believe the "-url" switch (which isn't included in the list of firefox command line arguments above) instructs firefox to treat the contents of %1 as a URL.&lt;/li&gt; &lt;li&gt;The Windows Shell which passes on the command line to the firefox application.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I'm going to attempt to draw the relevant part of the diagrams for IE and Firefox.&amp;nbsp; These are just my interpretations of what is happening, it's entirely possible that the dataflow is different in real life.&lt;/p&gt; &lt;p&gt;Firefox:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/ThreatModelingAgainThreatModelinginPract_C010/image.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="389" alt="image" src="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/ThreatModelingAgainThreatModelinginPract_C010/image_thumb.png" width="640" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;This diagram shows the flow of control from the user into Firefox (remember: I'm JUST diagramming a small part of the actual component diagram).&amp;nbsp; One of the things that makes Firefox's chrome engine so attractive is that it's easy to modify the chrome because the Firefox chrome is simply javascript.&amp;nbsp; Since the javascript being run runs with the same privileges as the current user, this isn't a big deal - there's no opportunity for elevation of privilege there.&amp;nbsp; But there is one important thing to remember here: Firefox has a security assumption that the -chrome command switch is only provided by the user - because it executes javascript with full trust, it's effectively accepts executable code from&amp;nbsp;the command line.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Internet Explorer:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/ThreatModelingAgainThreatModelinginPract_C010/image_2.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="398" alt="image" src="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/ThreatModelingAgainThreatModelinginPract_C010/image_thumb_2.png" width="640" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;This diagram describes my interpretation of how IE (actually urlmon.dll in this case) handles incoming URLs.&amp;nbsp; It's just my interpretation, based on the information contained &lt;a href="http://msdn2.microsoft.com/en-us/library/aa767914.aspx"&gt;here&lt;/a&gt;&amp;nbsp;(at a minimum, I suspect it's missing some trust boundaries).&amp;nbsp; The web page hands IE a URL, IE looks the URL up in the registry and retrieves a URL handler.&amp;nbsp; Depending on how the URL handler was registered, IE either invokes the shell on the path portion of the URL, or, if the URL handler was registered&amp;nbsp;as an &lt;a href="http://msdn2.microsoft.com/en-us/library/aa767916.aspx"&gt;async protocol hander&lt;/a&gt;, it hands the URL to the async protocol handler.&lt;/p&gt; &lt;p&gt;I'm not going to do a diagram for the firefoxurl handler or the shell, since they're either not interesting or are covered in the diagram above - in the firefoxurl handler case,&amp;nbsp;the firefoxurl&amp;nbsp;handler is registered as being handled by the shell.&amp;nbsp; In that&amp;nbsp;case,&amp;nbsp;&amp;nbsp;Internet Explorer will pass the URL into the shell, which will happily pass it onto the URL handler (which, in this case is FireFox).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;That's a lot of text and pictures, tomorrow I'll discuss what I think went wrong and how using threat modeling could have avoided the issue.&amp;nbsp; I also want to look at BOTH of the threat models and see what they indicate.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Obviously, the contents of this post are my own opinion and in no way reflect the opinions of Microsoft.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4987437" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item><item><title>Threat Modeling Again, Presenting the PlaySound Threat Model</title><link>http://blogs.msdn.com/larryosterman/archive/2007/09/17/threat-modeling-again-presenting-the-playsound-threat-model.aspx</link><pubDate>Mon, 17 Sep 2007 19:30:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4958743</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/4958743.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=4958743</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=4958743</wfw:comment><description>&lt;p&gt;It's been a long path, but we're finally at the point where I can finally present the threat model for PlaySound.&amp;nbsp; None of the information in this post is new, all the information is pulled from previous posts.&lt;/p&gt; &lt;p&gt;&amp;nbsp;----------------&lt;/p&gt; &lt;h1&gt;PlaySound Threat Model&lt;/h1&gt; &lt;p&gt;The PlaySound API is a high level multimedia API intended to render system sounds ("dings").&amp;nbsp; It has three major modes of operation:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It can play the contents of a .WAV file passed in as a parameter to the API.  &lt;li&gt;It can play the contents of a Win32 resource or other memory location passed in as a parameter to the API.  &lt;li&gt;It can play the contents of a .WAV file referenced by an alias.&amp;nbsp; If this mode is chosen, it reads the filename from the registry under HKCU\AppEvents.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&amp;nbsp;For more information on the PlaySound API and its options, see: &lt;a href="http://msdn2.microsoft.com/en-us/library/ms712879.aspx"&gt;The MSDN documentation for PlaySound&lt;/a&gt;.&lt;/p&gt; &lt;h2&gt;PlaySound Diagram&lt;/h2&gt; &lt;p&gt;The PlaySound API's data flow can be represented as follows.&lt;/p&gt; &lt;p&gt;&lt;img src="http://blogs.msdn.com/blogfiles/larryosterman/WindowsLiveWriter/ThreatModelingagain.DrawingtheDFD_955B/image_1.png"&gt;&lt;/p&gt; &lt;h2&gt;PlaySound Elements&lt;/h2&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Application: External Interactor - The application which calls the PlaySound API. &lt;li&gt;PlaySound: Process - The code that represents the PlaySound API &lt;li&gt;WAV file: Data Store - The WAV file to be played, on disk or in memory &lt;li&gt;HKCU Sound Aliases: Data Store - The Windows Registry under HKCU\AppEvents which maps from aliases to WAV filenames &lt;li&gt;Audio Playback APIs: External Interactor - The audio playback APIs used for PlaySound.&amp;nbsp; This could be MediaFoundation, waveOutXxxx, DirectShow, or any other audio rendering system. &lt;li&gt;PlaySound Command (Application-&amp;gt;PlaySound): DataFlow (Crosses Threat Boundary) - The data transmitted in this data flow represents the filename to play, the alias to look up or the resource ID in the current executable to play. &lt;li&gt;WAVE Header (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - The data transmitted in this data flow represents the WAVEFORMATEX structure contained in the WAV file being played. &lt;li&gt;WAV file Data (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - The data transmitted in this data flow represents the actual audio samples contained in the WAV file being played. &lt;li&gt;WAV filename (HKCU Sound Aliases -&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - The data transmitted in this data flow represents the contents of the HKCU\AppEvents\Schemes\.Default\&amp;lt;sound&amp;gt;\.Current[1] &lt;li&gt;WAV file Data (PlaySound -&amp;gt; Audio Playback APIs): DataFlow - The data transmitted in this data flow represents both the WAVEFORMATEX structure read from the WAV file and the audio samples read from the file.&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;PlaySound Threat Analysis&lt;/h2&gt; &lt;h3&gt;Data Flows&lt;/h3&gt; &lt;blockquote&gt; &lt;p&gt;WAVE Header (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Tampering &lt;br&gt;WAVE Header (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Information Disclosure &lt;br&gt;WAVE Header (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Denial of Service &lt;br&gt;WAV file Data (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Tampering &lt;br&gt;WAV file Data (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Information Disclosure &lt;br&gt;WAV file Data (WAV file-&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Denial of Service &lt;br&gt;WAV filename (HKCU Sound Aliases -&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Tampering &lt;br&gt;WAV filename (HKCU Sound Aliases -&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Information Disclosure &lt;br&gt;WAV filename (HKCU Sound Aliases -&amp;gt; PlaySound) : DataFlow (Crosses Threat Boundary) - Denial of Service &lt;br&gt;WAV file Data (PlaySound -&amp;gt; Audio Playback APIs): DataFlow - Tampering &lt;br&gt;WAV file Data (PlaySound -&amp;gt; Audio Playback APIs): DataFlow - Information Disclosure &lt;br&gt;WAV file Data (PlaySound -&amp;gt; Audio Playback APIs): DataFlow - Denial of Service&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Because all the Data flows are all within a single process boundary, there are no meaningful threats to those dataflows - the Win32 process model protects against those threats.&lt;/p&gt; &lt;h3&gt;External Interactors&lt;/h3&gt; &lt;blockquote&gt; &lt;p&gt;Application: External Interactor - Spoofing&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It doesn't matter which application called the PlaySound API, so we don't care about spoofing threats to the application calling PlaySound.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Application: External Interactor - Repudiation &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;There are no requirements that the&amp;nbsp;PlaySound API protect against Repudiation attacks.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Audio Playback APIs: External Interactor - Spoofing &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The system default APIs are protected by Windows Resource Protection so they cannot be replaced.&amp;nbsp; If an attacker does successfully inject his logic (by overriding the COM registration for the audio APIs or by some other means, the attacker is running at the same privilege level as the user, so can do nothing that the user can't do.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Audio Playback APIs: External Interactor - Repudiation &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;There are no requirements that the PlaySound API protect against Repudiation attacks.&lt;/p&gt; &lt;h3&gt;Data Stores&lt;/h3&gt; &lt;p&gt;Since the data stores involved in the PlaySound API are under the control of the user, we must protect against threats to those data stores.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;WAV file: Data Store - Tampering&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;An attacker can modify the contents of the WAV file data store.&amp;nbsp; To mitigate this attack, we will &lt;a href="http://blogs.msdn.com/larryosterman/archive/2007/07/24/playsound-is-failing-on-vista-what-s-wrong.aspx"&gt;validate the WAVE header information&lt;/a&gt;; we're not going to check the actual WAV data, since it's just raw audio samples.&amp;nbsp; Bug #XXXX filed to validate this mitigation. &lt;blockquote&gt; &lt;p&gt;WAV file: Data Store - Information Disclosure&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The WAV file is protected by NT's filesystem ACLs which prevent unauthorized users from reading the contents of the file. &lt;blockquote&gt; &lt;p&gt;WAV file: Data Store - Repudiation&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Repudiation threats don't apply to this store. &lt;blockquote&gt; &lt;p&gt;WAV file: Data Store - Denial of Service&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The PlaySound API will check for errors when reading from the store and will return an error indication to its caller (if possible). When PlaySound is running in the "resource or memory location" mode and the SND_ASYNC flag is specified, the caller may unmap the virtual memory associated&amp;nbsp;with the WAV file.&amp;nbsp; In that case, the PlaySound may access violate while rendering the contents of the file[2].&amp;nbsp; Bug #XXXX filed to validate this mitigation. &lt;blockquote&gt; &lt;p&gt;HKCU Sound Aliases:&amp;nbsp;Data Store - Tampering&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;An attacker can modify the contents of the sound aliases registry key.&amp;nbsp; To mitigate this attack, we will validate the contents of the key. Bug #XXXX filed to validate this mitigation. &lt;blockquote&gt; &lt;p&gt;HKCU Sound Aliases: Data Store - Information Disclosure&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The aliases key is protected by the registry ACLs which prevent&amp;nbsp;unauthorized users from reading the contents &amp;nbsp;of the key. &lt;blockquote&gt; &lt;p&gt;HKCU Sound Aliases: Data Store - Repudiation&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Repudiation threats don't apply to this store. &lt;blockquote&gt; &lt;p&gt;HKCU Sound Aliases: Data Store - Denial of service&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The PlaySound API will check for errors when reading from the store and will return an error indication to its caller (if possible).Bug #XXXX filed to validate this mitigation. &lt;h3&gt;Processes&lt;/h3&gt; &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - Spoofing&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Since PlaySound is the component we're threat modeling, spoofing threats don't apply. &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - Tampering&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The only tampering that can happen to the PlaySound process directly involves modifying the PlaySound binary on disk, if the user has the rights to do that, we can't stop them.&amp;nbsp; For PlaySound, the file is protected by &lt;a href="http://msdn2.microsoft.com/en-us/library/aa382503.aspx"&gt;Windows Resource Protection&lt;/a&gt;, which should protect the file from tampering. &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - Repudiation&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;We don't care about repudiation threats to the PlaySound API. &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - Information Disclosure&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The NT process model prevents any unauthorized entity from reading the process memory associated with the Win32 process playing Audio, so this threat is out of scope for this component. &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - Denial of Service&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Again, the NT process model prevents unauthorized entities from crashing or interfering with the process, so this threat is out of scope for this component. &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - Elevation of Privilege&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The PlaySound API runs at the same privilege level as the application calling PlaySound, so it is not subject to EoP threats. &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - "PlaySound Command" crosses trust boundary: Elevation of Privilege/Denial of Service / Tampering&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The data transmitted by the incoming "PlaySound Command" data flow comes from an untrusted source.&amp;nbsp; Thus the PlaySound API will validate the data contained in that dataflow for "reasonableness" (mostly checking to ensure that the string passed in doesn't cause a buffer overflow).&amp;nbsp; Bug #XXXX filed to validated this mitigation. &lt;blockquote&gt; &lt;p&gt;PlaySound: Process - "WAV file Data" data flow crosses trust boundary: Information Disclosure&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It's possible that the contents of the WAV file might be private, so if some attacker can somehow "snoop" the contents of the data they might be able to learn information they shouldn't.&amp;nbsp; Another way that this "I" attack shows up is described in &lt;a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-0675"&gt;CVE-2007-0675&lt;/a&gt; and &lt;a href="http://blogs.technet.com/msrc/archive/2007/01/31/issue-regarding-windows-vista-speech-recognition.aspx"&gt;here&lt;/a&gt;.&amp;nbsp; So how do we mitigate that threat (and the corresponding threat associated with someone spoofing the audio APIs)? &lt;p&gt;The risk associated with CVE-2007-0675 is out-of-scope for this component (if the threat is to be mitigated, it's more appropriate to handle that either in the speech recognition engine or the audio stack), so the only risk is that we might be handing the audio stack data that can be misused.&amp;nbsp;  &lt;p&gt;Since the entire APIs purpose is to play the contents of the WAVE file, this particular threat is considered to be an acceptable risk. &lt;p&gt;--- &lt;p&gt;[1] The actual path is &lt;em&gt;slightly &lt;/em&gt;more complicated because of SND_APPLICATION flag, but that doesn't materially change the threat model.&lt;/p&gt; &lt;p&gt;[2] The DOS issues associated with this behavior are accepted risks.&lt;/p&gt; &lt;p&gt;--------------&lt;/p&gt; &lt;p&gt;Next: Let's look at a slightly more interesting case where threat modeling exposes an issue.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4958743" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item><item><title>Threat Modeling Again, Pulling the threat model together</title><link>http://blogs.msdn.com/larryosterman/archive/2007/09/14/threat-modeling-again-pulling-the-threat-model-together.aspx</link><pubDate>Fri, 14 Sep 2007 17:58:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4912977</guid><dc:creator>LarryOsterman</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/larryosterman/comments/4912977.aspx</comments><wfw:commentRss>http://blogs.msdn.com/larryosterman/commentrss.aspx?PostID=4912977</wfw:commentRss><wfw:comment>http://blogs.msdn.com/larryosterman/rsscomments.aspx?PostID=4912977</wfw:comment><description>&lt;p&gt;So I've been writing a LOT of posts about the threat modeling process and how one goes about doing the threat model analysis for a component.&lt;/p&gt; &lt;p&gt;The one thing I've not talked about is what a threat model actually &lt;em&gt;is&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;A threat model is a specification, just like your functional specification (a Program Management spec that defines the functional requirements of your component), your design specification (a development spec that defines the architecture that is required to implement the functional specification), and your test plan (a test spec that defines how you plan on ensuring that the design as implemented meets the requirements of the functional specification).&lt;/p&gt; &lt;p&gt;Just like the functional, design and test specs, a threat model is a living document - as you change the design, you need to go back and update your threat model to see if any new threats have arisen since you started.&lt;/p&gt; &lt;p&gt;So what goes into the threat model document?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Obviously you need the diagram and an enumeration and description of the elements in your diagram.&amp;nbsp; &lt;/li&gt; &lt;li&gt;You also need to include your threat analysis, since that's the core of the threat model.&lt;/li&gt; &lt;li&gt;For each mitigated threat that you call out in the threat analysis, you should include the bug # associated with the mitigation&lt;/li&gt; &lt;li&gt;You should probably have a one or two paragraph description of your component and what it does (it helps an outsider to understand your diagram), similarly, having a list of contacts for questions, etc are also quite useful.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The third item I called out there reflects an important point about threat modeling that's often lost.&lt;/p&gt; &lt;p&gt;Every time your threat model indicates that you have a need to mitigate a particular threat, you need to file at least one bug and potentially two.&amp;nbsp; The first bug goes to the developer to ensure that the developer implements the mitigation called out in the threat model, and the second bug goes to a tester to ensure that the tester either (a) writes tests to verify the mitigation or (b) runs existing tests to ensure that the mitigation is in place.&lt;/p&gt; &lt;p&gt;This last bit is really important.&amp;nbsp; If you're not going to follow through on the process and ensure that the threats that you identified are mitigated, then your just wasting your time doing the threat model - except as an intellectual exercise, it won't actually help you improve the security of your product.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Next: Presenting the PlaySound threat model!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4912977" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Software+Engineering/default.aspx">Software Engineering</category><category domain="http://blogs.msdn.com/larryosterman/archive/tags/Security/default.aspx">Security</category></item></channel></rss>