<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>David LeBlanc's Web Log</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/david_leblanc/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/david_leblanc/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 04:59:14 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SafeInt moved to github</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/safeint-moved-to-github</link>
      <pubDate>Thu, 22 Mar 2018 21:18:37 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/?p=995</guid>
      <description><![CDATA[Has it really been 7 years since I last posted? Yikes - wonder if anyone will see this.

The main...]]></description>
      <content:encoded><![CDATA[Has it really been 7 years since I last posted? Yikes - wonder if anyone will see this.

The main news is that CodePlex is kaput, and while SafeInt is archived, the archive unhelpfully stripped off the file names. So it has been moved to GitHub, which is much better. All of the history from CodePlex has been preserved, and while I was at it, I checked to be sure that it still compiles properly on gcc, clang and latest couple of Visual Studio versions.

Then I enhanced the test suite, made make files for gcc and clang, and prodded by Dan Jump, added constexpr support. This resulted in several changes, none that would matter at runtime. There was also a corner case bug in the routine that deals with initializing a SafeInt from floating point, and that is now fixed.

I'm even batting around the idea of submitting it to Boost.

Oh, and a link to GitHub would be a good idea, d'oh - https://github.com/dcleblanc/SafeInt]]></content:encoded>
    </item>
    <item>
      <title>Compilers, Integers and Optimizations</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/compilers-integers-and-optimizations</link>
      <pubDate>Fri, 23 Dec 2011 11:18:06 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2011/12/23/compilers-integers-and-optimizations/</guid>
      <description><![CDATA[I've had a good bit of fun (for some value of fun) with hardening SafeInt against what I consider to...]]></description>
      <content:encoded><![CDATA[<p>I've had a good bit of fun (for some value of fun) with hardening SafeInt against what I consider to be some nasty compiler tricks. The problem is that as soon as the compiler hits something that's technically undefined by the C++ standard, they're actually allowed to do anything they want, short of uploading your source to someone else's server. The first round of this was something I wrote about in <a href="https://blogs.msdn.com/b/david_leblanc/archive/2008/04/04/evil-compiler-tricks-and-checking-for-pointer-math.aspx">Evil compiler tricks ...</a>, where checking to see if pointer math was relatively correct by adding the offset to the pointer, and see if the result got smaller is foiled because pointer addition isn't defined outside of the buffer, and wrapping around is certainly outside of the buffer.
</p><p>The problem is solved by casting the pointers to size_t, which forces unsigned addition, and wrap-around is defined for this. So the next round is that some compilers (gcc and Intel are two of the most notable) get really aggressive about some of this, and will start tossing out things like:
</p><p><span style="font-family:Consolas; font-size:9pt">if( x + y &lt; x )
</span></p><p><span style="font-family:Consolas; font-size:9pt">   return false;
</span></p><p>
 </p><p>What's truly obnoxious about this is that it really isn't undefined. A compiler _has_ to know what architecture it is generating code for, and at the assembly level, this is quite well defined. Let's look at why the standard thinks that this isn't defined – the problem is that there are several ways to represent negative integer numbers – if you're interested in a refresher on this, a good write up is <a href="https://en.wikipedia.org/wiki/Signed_number_representations">Signed number representations</a>. Just about every processor that's in common, current use uses two's complement. The standard basically has two options – either define a signed addition rollover behavior for every signed number representation that's allowed, or take the easy way out and punt it as undefined. Unfortunately, even the most recent standard takes the easy way out.
</p><p>But is it <em>really</em> undefined? I don't think so – let's look at what the compiler does with both signed and unsigned addition on x86:
</p><p>Here's signed:
</p><p><span style="font-family:Consolas; font-size:9pt">add         eax,dword ptr [argc]
</span></p><p>
 </p><p>And here's what happens when we change it to unsigned:
</p><p><span style="font-family:Consolas; font-size:9pt">add         eax,dword ptr [argc]
</span></p><p>
 </p><p>See the difference? Nope, I don't see it, either. Looks like the same thing. A compiler absolutely <em>has</em> to know that on this architecture, signed and unsigned addition are really the same thing at processor level, and the only difference is how you interpret the result. This makes for a handy work-around – if you do have an overly ambitious compiler, or as my friend Mike puts it, an "impractical compiler", and it is tossing out your int overflow checks, what you can do is cast to unsigned. While the compiler may toss out our example above, it won't toss out:
</p><p><span style="font-family:Consolas; font-size:9pt">if( (unsigned int)x + (unsigned int)y &lt; (unsigned int)x )
</span></p><p><span style="font-family:Consolas; font-size:9pt">   return false;
</span></p><p>
 </p><p>Due to Jeffrey Walton of the OWASP project helping me to flesh out the SafeInt test harness, we were able to catch several places where the gcc compiler was throwing out validation code, and the Intel compiler was even more aggressive about it. The fixes were all along the same lines as the above. One thing I'd like to fess up to is that a co-worker, Ahmed Charles, warned me about this a while ago, I argued about it, he was right, and I should have listened.
</p><p>Just when we thought we'd gotten it all taken care of, along comes John Regehr and his grad students with <a href="https://blog.regehr.org/archives/593">Overflows In SafeInt</a>. Yikes! Not what I want to wake up to. So what's the problem? As it turns out, unary negation of min int is also undefined by the standard. This is yet another example of a place where it isn't <em>really</em> undefined – it's (~x + 1), which happens to return the same result.
</p><p>How does this get to be a problem? If the impractical compiler doesn't know at compile time what the number is, then it just has to emit the same assembly, and if something hands the function min int, then it does what we expect it to do, and the right thing may or may not happen, depending on whether you expect –MIN_INT == MIN_INT. Ah, but what John's team did was to hand SafeInt a bunch of cases where one of the values was a compile-time constant of MIN_INT, and then we had various malfunctions when compiling with impractical compilers. So yes, this is a bug, but it's a very seriously small corner case.
</p><p>I'm also going to argue strongly that any compiler that does such a thing is doing something very dangerous. If you have an inline function, and you pass it a value known at runtime, then it emits a certain set of assembly, and if you pass it something known at compile time, then it behaves differently (as in functionally differently – you're welcome to optimize to make it do the same thing faster). This is an absolutely awful thing to do to a dev – hand them something that will only repro in a ship build, and which can only be debugged in assembly. If you're trying to make things really difficult for a developer, that's a great approach.
</p><p>Now let's look at what we do about it – if we can't count on unary negation to function reliably, what's the solution? If we drop back to how we negate things using two's complement manually, we have:
</p><p>(~x + 1)
</p><p>But wait – the '~' operator will emit a signed int (for the types we're interested in – unary negation of unsigned numbers is usually a bug). I just explained above that signed addition wrap-around is undefined, and that nasty, impractical, fiendish compiler already knows that x == MIN_INT, and they'll toss out my code. So the solution is (for ints):
</p><p>(int)(~(unsigned int)x + 1)
</p><p>This does the right thing, and forces the compiler to do the right thing, because now everything is defined by the standard. As a developer, it's monstrously inconvenient, and the best thing to do is to make a couple of template specializations to cover 32 and 64-bit incarnations of the problem. Something that's nice is that even though the code is guaranteed to baffle most new devs, the compiler does emit the same assembly as it would otherwise, so it isn't a performance hit.
</p><p>Oh and one last thing – look out for code like so (where x is positive and 32-bit):
</p><p><span style="font-family:Consolas; font-size:9pt">if( x + sizeof(Y) &lt; x )
</span></p><p><span style="font-family:Consolas; font-size:9pt">   return false;
</span></p><p>
 </p><p>On a 32-bit system, this will work as expected, but on a 64-bit system, sizeof(y) is an unsigned __int64, the addition is up cast to 64-bits, and now the addition is exceedingly unlikely to roll over. The right fix here is to use SafeInt, and let us worry about all this weird integer stuff, or you can ensure things work like you want by writing it this way:
</p><p>
 </p><p><span style="font-family:Consolas; font-size:9pt">if( x + (unsigned int)sizeof(Y) &lt; x )
</span></p><p><span style="font-family:Consolas; font-size:9pt">   return false;
</span></p><p>
 </p>]]></content:encoded>
    </item>
    <item>
      <title>Bugs and Consequences</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/bugs-and-consequences</link>
      <pubDate>Thu, 22 Dec 2011 10:37:16 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2011/12/22/bugs-and-consequences/</guid>
      <description><![CDATA[I've been meaning to write about overzealous compilers, and nice geeky things, but I'm going to use...]]></description>
      <content:encoded><![CDATA[<p>I've been meaning to write about overzealous compilers, and nice geeky things, but I'm going to use this forum to vent a bit. When I make a bug that messes up a customer, I generally have to fix it. I'm fairly often face to face with the customer, and sometimes all I can do is apologize and offer to fix it in the next version. When I've worked in other customer-oriented jobs, like restaurants, if the customer isn't happy, you have to do _something_. Even if it's small, you have to do _something_.
</p><p>I've been using Toshiba laptops for the last 15 years, and they have generally made good products – we had a few that cooked themselves, but that was a while ago and the one I have now has been humming along for about 3 years. I've tended to recommend them to others. I think this is the 6<sup>th</sup> one I've had.
</p><p>So on the day after Thanksgiving (actually 9PM Pacific time), I helped a friend order a laptop at a very good price. Time passes, no laptop. I go and look on the site for order status, nada – the system somehow didn't process my order. I know for a fact that I went all the way through the screens, was told the order was placed. What should have cued me to investigate earlier was that I didn't immediately get a confirmation e-mail.
</p><p>Finally, today I call them up, and we've got a situation – their system clearly doesn't have the order, and they can't know whether I'm telling the truth or trying to social engineer them. The fact I've ordered from them before ought to tell them something.
</p><p>I ask them what they can do about this – I'm not expecting them to offer me the original deal, though that would be nice if they did. The first guy isn't authorized to do anything, but the first-line customer support people never are. He gets a manager on the line, and he tells me that he'll do nothing about it. I press him a little – he's got to have _some_ latitude to do _something_. Nope, nada, zip, you're an upset customer who got screwed out of money by our bug, and we don't care.
</p><p>He then admits that they get hundreds of calls like this, and the policy is to just blow them all off. I think if you get hundreds of bug reports, they're not all people who are trying to rip you off. Some of them might be real customers with a real problem.
</p><p>I press him a bit more – there's got to be some _small_ thing he can do – throw in some cheap accessory, _something_. Nope, zip, not going to help you. Maybe I've just spoken to the wrong person – this manager clearly has very poor customer service skills, and I'm sure that at this time of year, people are busy and nerves are frayed. Even so, I'm really torn – I hate to do business with a company that won't take care of a problem.
</p><p>Disclaimer – this is very obviously NOT a statement on behalf of my employer. We buy a zillion laptops every year, we've got reps who handle our account, and I'm sure they're better at customer service than this guy.</p>]]></content:encoded>
    </item>
    <item>
      <title>Another technique for Fixing DLL Preloading attacks</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/another-technique-for-fixing-dll-preloading-attacks</link>
      <pubDate>Mon, 23 Aug 2010 17:19:00 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2010/08/23/another-technique-for-fixing-dll-preloading-attacks/</guid>
      <description><![CDATA[Back in February, 2008, I posted on DLL preloading attacks and how to avoid them here. It seems that...]]></description>
      <content:encoded><![CDATA[<p>Back in February, 2008, I posted on DLL preloading attacks and how to avoid them <a href="https://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspx">here</a>. It seems that the problem has recently gotten a lot of attention &ndash; currently called "Binary Planting". You can read more about that at the <a href="https://blogs.technet.com/b/msrc/archive/2010/08/21/microsoft-security-advisory-2269637-released.aspx">MSRC blog</a>, the <a href="https://blogs.technet.com/b/srd/archive/2010/08/23/more-information-about-dll-preloading-remote-attack-vector.aspx">SWI blog</a>, on this ZDNET <a href="https://www.zdnet.com/blog/security/hd-moore-critical-bug-in-40-different-windows-apps/7188">blog post</a>, an <a href="https://www.zdnet.com/blog/security/details-emerge-on-new-dll-load-hijacking-windows-attack-vector/7204">update</a>, and a <a href="https://www.computerworld.com/s/article/9181513/Hacking_toolkit_publishes_DLL_hijacking_exploit">Computerworld article</a>. </p>
<p>In addition to the advice I gave previously, I recently thought of a simple way to avoid problems. The technique is simply to push the current working directory, set it to something safe, like c:\windows\system32, call LoadLibrary, and then reset it to the previous current working directory. Note that if you can call SetDllDirectory(""), as I documented in my previous post, then you should do that, as it is easier and will solve the problem for all your LoadLibrary calls. If you cannot do that, here's a code sample that will fix individual calls for you: </p>
<p><span style="font-family:Courier New; font-size:10pt">HMODULE SafeLoadLibrary(<span style="color:blue">const</span> <span style="color:blue">wchar_t</span>* wzFileName) </span></p>
<p><span style="font-family:Courier New; font-size:10pt">{ </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">static</span> <span style="color:blue">wchar_t</span> wzSystem[MAX_PATH]; </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">wchar_t</span> wzCurDir[MAX_PATH]; </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;HMODULE hMod = NULL; </span></p>
<p>&nbsp;</p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>(wzSystem[0] == L<span style="color:#a31515">'\0'</span>) </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;{ </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>(GetSystemDirectory(wzSystem, _countof(wzSystem)) == 0) </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">return</span> NULL; </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>
<p>&nbsp;</p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">// Now get the actual current working directory </span></span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>(GetCurrentDirectory(_countof(wzCurDir), wzCurDir) == 0) </span></p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wzCurDir[0] = L<span style="color:#a31515">'\0'</span>; </span></p>
<p>&nbsp;</p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;SetCurrentDirectory(wzSystem); </span></p>
<p>&nbsp;</p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;hMod = LoadLibrary(wzFileName); </span></p>
<p>&nbsp;</p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;SetCurrentDirectory(wzCurDir); </span></p>
<p>&nbsp;</p>
<p><span style="font-family:Courier New; font-size:10pt">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">return</span> hMod; </span></p>
<p><span style="font-family:Courier New; font-size:10pt">}</span> </p>
<p>A nice feature of this code is that if the library you're loading might not have this fix and loads additional DLLs, it's been made safe by your changing the current working directory to something that's known good. A drawback of this code is that if some other thread is changing your current working directory, the two threads could have a race condition. This would be an unusual problem, but something to be aware of. </p>
<p>Obviously, if you need the current working directory in your search path, then this won't help, and it is up to you to ensure that the current working directory isn't something under an attacker's control. </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>MS10-048 – Getting the Math Right</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/ms10-048-getting-the-math-right</link>
      <pubDate>Tue, 10 Aug 2010 15:12:00 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2010/08/10/ms10-048-getting-the-math-right/</guid>
      <description><![CDATA[The Security Research and Defense blog detailed an integer overflow here. The code looks like this:...]]></description>
      <content:encoded><![CDATA[<p>The Security Research and Defense blog detailed an integer overflow <a href="https://blogs.technet.com/b/srd/archive/2010/08/10/ms10-048-an-explanation-of-the-defense-in-depth-fixes.aspx">here</a>. The code looks like this: </p>
<p style="background: white"><span style="color:#333333"><span style="font-size:10pt"></span><span style="font-size:8pt">case DBT_DEVTYP_PORT:</span><span style="font-family:Times New Roman; font-size:12pt"> </span></span></p>
<p style="background: white"><span style="color:#333333"><span style="font-size:8pt">pPortW = (PDEV_BROADCAST_PORT_W)lParam;</span><span style="font-family:Times New Roman; font-size:12pt"> </span></span></p>
<p style="background: white"><span style="color:#333333"><span style="font-size:8pt">if ((1+wcslen(<span style="background-color:yellow">pPortW-&gt;dbcp_name</span>))*sizeof(WCHAR) + FIELD_OFFSET(DEV_BROADCAST_PORT_W, dbcp_name) &gt; cbSize) {</span><span style="font-family:Times New Roman; font-size:12pt"> </span></span></p>
<p style="background: white"><span style="color:#333333"><span style="font-size:8pt">MSGERRORCLEANUP(0);</span><span style="font-family:Times New Roman; font-size:12pt"> </span></span></p>
<p style="background: white"><span style="color:#333333"><span style="font-size:8pt">}</span><span style="font-family:Times New Roman; font-size:12pt"> </span></span></p>
<p style="background: white"><span style="color:#333333"><span style="font-size:8pt">break;</span><span style="font-family:Times New Roman; font-size:12pt"> </span></span></p>
<p>They then claimed that it would take a wcslen of greater than 2^31 to cause an overflow, but this isn't true. Let's take a look at the math: </p>
<p>Let: </p>
<p>wcslen(pPortW-&gt;dbcp_name) be len </p>
<p>FIELD_OFFSET(DEV_BROADCAST_PORT_W, dbcp_name) be offset (practically a small, fixed value) </p>
<p>We now have the following equation: </p>
<p>Size = ( 1 + len ) * 2 + offset </p>
<p>If Size &gt; 2^32 -1, then we have an overflow, so let's solve for that: </p>
<p>2^32 -1 &lt; ( 1 + len ) * 2 + offset </p>
<p>Now, </p>
<p>2^32 &ndash; (1 + offset) &lt; (1 + len ) * 2 </p>
<p>2^31 &ndash; ( 1 + offset )/2 &lt; 1 + len </p>
<p>And finally: </p>
<p>2^31 &ndash; (1+offset)/2 -1 &lt; len </p>
<p>So the length of the string doesn't need to be larger 2^31 &ndash; there's actually a window of (1+offset)/2 -1 where an overflow can actually occur. Now practically, it is difficult to get a string that long into the system, but it isn't impossible &ndash; we can allocate 2^31-1 bytes if there's actually enough memory. </p>
<p>BTW, the above code is a good reason why one should use wcsnlen. If we'd done this: </p>
<p>Size_t cchName = wcsnlen(pPortW-&gt;dbcp_name, SANE_LENGTH); </p>
<p>If( cchName == SANE_LENGTH) ||<br />( existing sanity check ) ) </p>
<p>Then you won't have to worry about int overflows because if we constrain len to something that isn't ridiculous, we also don't have integer overflows. But if you are going to analyze an expression for int overflows, don't guess at a range. Work out the math, just like I did here, and know exactly the constraints. In this particular case, it didn't hurt anything to be imprecise, but there are a lot of cases where the attacker finds the corner case and exploits it.</p>
<p>[8/11 - Update]</p>
<p class="MsoNormal" style="margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto;"><span style="font-family: 'Arial','sans-serif'; color: black; font-size: 9pt;">While I did show how to correctly analyze for the exact sizes that cause integer overflows, I did make a mistake on the allocation size, which is slightly less than 4GB, and that can't be allocated on any 32-bit system, thus&nbsp;as the SRD blog correctly indicated </span><span style="font-family: 'Arial','sans-serif'; color: black; font-size: 9pt;">the allocation isn't possible. The main point, which is not to guess at the sizes, but to work them out exactly remains an important technique to remember.<o:p></o:p></span></p>]]></content:encoded>
    </item>
    <item>
      <title>Acrobat is Getting a Sandbox</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/acrobat-is-getting-a-sandbox</link>
      <pubDate>Tue, 20 Jul 2010 09:19:40 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2010/07/20/acrobat-is-getting-a-sandbox/</guid>
      <description><![CDATA[We've been helping Adobe to get a sandbox going which is similar to what we used in Office 2010 for...]]></description>
      <content:encoded><![CDATA[<p>We've been helping Adobe to get a sandbox going which is similar to what we used in Office 2010 for Protected View. Their blog post about it is <a href="https://blogs.adobe.com/asset/2010/07/introducing-adobe-reader-protected-mode.html">Introducing Adobe Reader Protected Mode</a>. I'm excited that the sandboxing approaches that we've pioneered in Office, starting with a sandbox for our search subsystem, the MOICE sandbox, and finally Protected View is going to be useful in helping protect the customers we have in common with our partners.
</p><p>It's been interesting working with Adobe – Office and Adobe compete on many fronts, but we put all that aside when it comes to helping protect customers from security issues.</p>]]></content:encoded>
    </item>
    <item>
      <title>DSig Q &amp; A</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/dsig-q-a</link>
      <pubDate>Sun, 30 May 2010 22:38:46 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2010/05/30/dsig-q-a/</guid>
      <description><![CDATA[I'm going to cover the answers to some of the questions that came in after Shelley answered the...]]></description>
      <content:encoded><![CDATA[<p>I'm going to cover the answers to some of the questions that came in after Shelley answered the first round in her <a href="https://blogs.technet.com/b/office2010/archive/2009/12/08/digital-signitures-in-office-2010.aspx?PageIndex=2">post</a>.
</p><p><strong>Q: What will happen if I try to verify a doc signed in 2010 in office 2007/Office 2007 ?
</strong></p><p>A: I'm assuming that the person asking meant 2007/2003. Office 2007 doesn't understand XAdES extensions, and can't use it to ignore an expiration. If the certificate isn't expired or revoked, it will evaluate the signature just fine. Note – there was a requirement that all top-level Reference elements had to be to an Object element. If Office 2007 is rejecting a valid Office 2010 signature, it means you haven't applied recent updates. Go apply your security patches, which will update MSO.dll to the latest version, and the problem will be solved. There's also a QFE for it, but I don't know the number.
</p><p>This also depends on the algorithms used – Office 2007 doesn't understand hashing algorithms other than SHA-1 being used in a signature, and can't yet use CNG public key algorithms.
</p><p>Office 2003 (and earlier) doesn't recognize XML-DSIg signatures at all, and will see the document as unsigned. This is unfortunate, but the last service pack for Office 2003 went out a while back. We're going to try very hard to not put you into that situation again.
</p><p><strong>Q: Mihail Romanov asked: Shelly, how can i use national algorithms, e.g. GOST (national standard in Russia), for digital signatures in Office 2010?
</strong></p><p>A: This is a bit of a problem. The XML-DSig standard specifies that the algorithm has to be cited as a URI, for example, here's SHA-1:
</p><p>&lt;DigestMethod Algorithm="https://www.w3.org/2000/09/xmldsig#sha1"/&gt;
</p><p>The URI's available to us are defined in <a href="https://www.rfc-editor.org/rfc/rfc4051.txt">RFC 4051</a>, and unfortunately GOST isn't one of them. The XML-DSig standard does not specify how to deal with a situation where you have an algorithm that's not listed. I've asked about this, and was told you could put anything in there, but that won't interoperate with other implementers, which isn't the best situation. I would like it if the XML-DSig committee could please clarify this – one suggestion I might make would be for the Algorithm attribute to be either an URI or an algorithm OID – the algorithm OID should be something one could interoperate with. Another suggestion would be to make a DigestMethod element with a more robust way of expressing algorithms. I would personally like to solve this problem, but I don't have a solution at the moment. It is also a bit of a problem that Windows doesn't ship an implementation of GOST, but if we could overcome the URI issue and you had a CNG plug-in for GOST hashing and public key operations, then this could be fixed.
</p><p><strong>Q: It looks like Office 2010 Beta doesn't support certificates with private keys stored in third-party CSPs on Windows 7 and Vista. Word, Excel, PowerPoint fail to sign documents with such certificates.
</strong></p><p>A: Yes, there was a bug there. We'll fix that – not sure exactly when the fix will be available. Stay tuned. If it is possible, us a CNG plug-in, which will work fine.
</p><p><strong>Q: Great to see XAdES being adopted in Office 2010. Disappointed though that looking at the signature produced the content of most of the elements of the XAdES object in the _xmlsignatures\sig1.xml were empty. Is there a beta available with the completed XAdES object?
</strong></p><p>A: The full release version will take you up to XAdES-X-L. As I noted in my last post, there's a number of the elements that we haven't done anything with yet. Implementing everything possible would be quite a bit of work. If you read the last post, which of the elements that we haven't used yet seem most useful?
</p><p><strong>Q: Will OneNote 2010 support digital signatures? OneNote would be perfect for a electronic laboratory notebook if only it supported digital signatures for intellectual property purposes.
</strong></p><p>A: Interesting suggestion. OneNote likes to update notebooks constantly, and might be a challenge to sign. To be very honest, we hadn't thought of that yet. We should look into it. Thanks for the feedback.</p>]]></content:encoded>
    </item>
    <item>
      <title>Office 2010 Digital Signatures and XAdES</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/office-2010-digital-signatures-and-xades</link>
      <pubDate>Sun, 30 May 2010 21:59:00 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2010/05/30/office-2010-digital-signatures-and-xades/</guid>
      <description><![CDATA[Shelley Gu, the program manager for Office signatures, has already posted the PM version of what...]]></description>
      <content:encoded><![CDATA[<p>Shelley Gu, the program manager for Office signatures, has already posted the PM version of what we've done to improve digital signatures in the Office 2010 Engineering blog back in December. Her post is <a href="https://blogs.technet.com/b/office2010/archive/2009/12/08/digital-signitures-in-office-2010.aspx">here</a>. While Shelley did a nice job of an overview for the average user, I'd like to dive a bit more into detail. I also noticed that there are a bunch of comments to her post that haven't been answered, and I'll do that in a following post here.
</p><p>While there have been a number of improvements, the biggest change has been the addition of XAdES. XAdES is an extension to the XML-DSig that provides for a number of improvements, and allows for very long-lived signatures. The first specification for XAdES showed up at <a href="https://www.w3.org/TR/XAdES/">https://www.w3.org/TR/XAdES/</a>, and dates back to 2003. The full, most recent specification is 1.4.1, and can be found at <a href="https://uri.etsi.org/01903/v1.4.1/ts_101903v010401p.pdf">https://uri.etsi.org/01903/v1.4.1/ts_101903v010401p.pdf</a>. It takes a bit of poking around to find the exact link to the PDF, but I confirmed that the link worked and is valid as of this writing (5/30/2010).
</p><p>Getting XAdES into Office turned out to be a bit of an adventure. It started off with a request to add time stamping support, and it all had to be done in a big hurry, and we'd decided not to use XAdES, because it was supposedly hard. The first iteration was very non-standard. Once I'd gotten it done, then all of a sudden we just had to use XAdES, and we were in a big hurry for that, too. Some grumbling ensued, but I went off and did it. We first implemented up to XAdES-T (explained in a moment), which is what shipped in beta 2. Some time passed, Shelley came along, and then we decided we just had to have nearly full XAdES support, taking us up to XAdES-X-L, and that needed to be done in a hurry, too (are you sensing a theme?). Getting that part done happened after beta 2, which was just short of a miracle – not much makes the bar at that stage of the game. We've ended up with XAdES support for Word, Excel, PowerPoint and InfoPath.
</p><p>Now that I've been able to examine the gory details of XAdES, I'm really glad we chose to support it. The signatures we can create are far more robust than what went before, and best of all, they're backwards compatible (at least to Office 2007 – Office 2003 is ignorant of XML signatures). There's a bunch of cool (assuming you're a signature geek) stuff to work with.
</p><p>There are several levels to XAdES, and a bunch of optional elements that one could implement going forward – here's the list:
</p><ul><li>BES – the most basic XAdES signature
</li><li>EPES – same as above, but it has a SignaturePolicyIdentifier element. This is the form that we create by default, though it is only technically EPES – the SignaturePolicyIdentifier only has the default element.
</li><li>T – adds a timestamp. I'd like it if this were the default, but we don't have a default timestamp server.
</li><li>C – adds hashes and verifying information for the certificate chain and the corresponding revocation responses, whether these are CRT or OCSP responses.
</li><li>X – adds a timestamp that covers the original signature, and any information added in the T and C forms.
</li><li>X-L – as above, but now we have full copies of the cert chain and the revocation responses.
</li><li>A – archival – not yet implemented by Microsoft Office
</li></ul><p>OK, but what's the reason for all this? The BES/EPES levels add a couple of minor items, and one that's interesting and critical to have. The first is the SigningTime – this is something that's not really in the XML-DSig standard, and we invented a reasonable way to store it in our app-specific Object. The existing implementation for ODF signatures in Open Office has done exactly the same thing. With XAdES support, now we have a standard way to store the signing time.
</p><p>The second major item is the SigningCertificate element. This covers a really subtle attack that the XML-DSig specification didn't think of. There are real world situations where a certificate server might re-issue a certificate that has the same public and private keys as a previously issued certificate. If you had 2 certificates with the same keys, then you could substitute one for the other, and XML-DSig wouldn't be able to tell the difference – the signature would verify just fine. This doesn't seem like a problem, but let's say I had 2 certificates, one is expired, and the other isn't. Now I sign a contract with the newer certificate, and later I want out of the contract. If I can substitute in the older certificate for the newer one, then I have an expired signature, and can repudiate the signature – it isn't valid! The SigningCertificate element takes a hash of the full X509 data used to make the signature, and makes that part of the signed data – now these attacks can be caught.
</p><p>There are a number of additional optional elements included in XAdES-BES/EPES that we don't use yet – I'll discuss those later.
</p><p>The next level, XAdES-T is where you really get a lot of benefit. A serious problem with XML-DSig signatures is that they're not good for the long term. You are typically given a certificate that's good for 1-2 years, you sign something, and then open it 2 years later, and it's invalid. We can't replace pen and paper this way – real signatures have to be good for many years. The solution is a SignatureTimeStamp element. This uses <a href="https://www.rfc-editor.org/rfc/rfc3161.txt">RFC 3161</a> to record a timestamp of the signature value. Assuming that we can trust the timestamp server, we now have external proof of the signing time. This means that a future expiration doesn't apply, and a revocation may not apply.
</p><p>I'll digress a bit and explain some of the ins and outs of expiration and revocation, and why an expired certificate should be treated the same as if it were revoked. A core problem with using CRLs (certificate revocation lists) is that they get big. When they get big, they can clog networks, and cause timeouts. One way to manage this is to just not keep revocation information for anything that's expired – you're not supposed to trust an expired cert in any case. Whether or not this happens is up to the CA operator, and hopefully will become less common as we all move to OCSP responses, which is a better system where you get an answer for that one cert, not all the certs that have ever been revoked.
</p><p>If we can prove that something was signed prior to expiration, we can now safely ignore the expiration. Revocation is a different matter, and depends on when the revocation occurs and whether it was backdated. Let's say I sign something today, and then next week find out that my certificate has been exposed to an attacker. I then figure out that the attacker got me a month ago, and I'd then go revoke the cert as of a month ago. The rub here is that if I verify the signature in the next few days, it seems valid. If I verify it in a month, then it was signed after the revocation happened, and it isn't valid. If I verify it in 2 years, and the revocation information has gone away, now it's valid again! So we've made some progress, but there's clearly more to be done. Fortunately, XAdES has solutions for these problems as well.
</p><p>An immediate solution is to not timestamp something immediately – you could add the timestamp later. As long as you add the timestamp prior to expiration, and check for validity at the time you add the timestamp, then we have more assurance of the revocation status. The second part of the solution is to go to the higher levels – and note that all of these are additive if you start with XAdES-BES/EPES.
</p><p>XAdES-C is a little bit of an odd level. I can't understand why anyone would ever use it in most real scenarios. What's added here are hashes and issuer information for the entire certificate chain, and hashes and identifying information for the revocation responses. This assumes that we have some external store for the certificates and responses, but doesn't say anything about where to go find them. We'll allow you to create XAdES-C signatures, but I wouldn't recommend it. If we have the extended levels, then this information becomes critical.
</p><p>XAdES-X provides a key piece of critical assurance – now we add a timestamp over the signature, any XAdES-T timestamps, and the information we added for XAdES-C. This has now created a situation where we can identify that the certificate chain was valid, and revocation information was obtained at a specific point in time, and more importantly, protected the XAdES-C information from tampering. Like the predecessor, I don't recommend stopping here.
</p><p>XAdES-X-L now includes the full certificate chain, and full copies of the CRLs (these could get big) or OCSP responses (much better). If you're going to go past XAdES-T, this is really the next practical stop.
</p><p>If you can add all of this in stages - not a current capability of Office, but something that could be done with a utility – then if the XAdES-X-L information is added just prior to expiration, you now have a very high assurance that the signature is valid, nearly indefinitely. Ah, but cryptographic algorithms seem to degrade over time. In the time I've been working with these, we've seen MD5 go from shaky to useless, and SHA-1 will no longer meet EU or US standards as of 1/1/2011, which is right around the corner. SHA-1 isn't in the same bucket as MD5, but we expect that it will get there. It isn't out of the question that over time, the same thing will happen to SHA-256, and so on. To make matters worse, the public keys start getting creaky if they're less than 2048 bits, and we can expect these to progressively degrade as well.
</p><p>The solution to the problem of "algorithm rot" is in XAdES-A – this provides for an archival timestamp, and assuming that the archival timestamp uses a better set of algorithms, we've now extended the life of the signature. If you keep doing this on a regular basis, you could have a signature remain valid long after the original core crypto used to create it became worthless, which is a really neat trick. I've got a tremendous amount of respect for the people who created XAdES – they  have a really elegant solution to a lot of problems. I've only found a few ambiguous parts of the specification that were a problem for me.
</p><p>In addition to all the nice features above, there's also a number of optional items that could be useful in the future:
</p><ul><li>SignaturePolicyIdentifier – what sort of signature is it? Full document, partial document?
</li><li>CounterSignatures – these are obviously useful
</li><li>DataObjectFormat – you sign what you see, and what you see should be what you sign. This can be used to help clarify just how to view the data.
</li><li>ComittmentType – what you mean by this signature
</li><li>SignatureProductionPlace – where you signed it
</li><li>SignerRole – also obvious
</li><li>Data objects timestamps – can be used to show when data were created
</li></ul><p>I'm also working with the ODF board to hopefully get XAdES signatures into the ODF 1.2 specification so that we can all create signatures that will interoperate between all of the implementers of the ODF standard. So far, my proposals seem to be well received, and really happy that it has gone well thus far.
</p><p>Next post will cover some of the questions I see unanswered on Shelley's post.</p>]]></content:encoded>
    </item>
    <item>
      <title>New “Improved” Site</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/new-improved-site</link>
      <pubDate>Sun, 30 May 2010 20:26:40 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2010/05/30/new-improved-site/</guid>
      <description><![CDATA[Hrmph. So they managed to disappear my last post, and now my blog looks really generic. I liked the...]]></description>
      <content:encoded><![CDATA[<p>Hrmph. So they managed to disappear my last post, and now my blog looks really generic. I liked the way it used to look, thankyouverymuch.
</p><p>Then I discovered that while Word on my laptop somehow knew the right password, I didn't have it written down anywhere. Used to just be easy to reset, but now I can't link my Live ID to the site without it, and I'm dead in the water.
</p><p>Option 1 was to go write an app that would go do CryptUnprotectData on what's stored in the registry on my laptop, but I couldn't remember if we used any entropy, and I don't have source access from home (in an attempt to keep myself from working too much). I could try it, but then I remembered that most of the blogging protocols just send the password in the clear, and while that's completely ridiculous for a protocol invented this century to do that, it came in handy.
</p><p>Having an actual firewall as my gateway, I could then just pop up a network monitor, go make a post, and sniff the traffic. Voila! There's the password, now I'm back in business. Comes in handy being a hacker.
</p><p>I should make a tool to export blog settings, and then import them back again into a different system…
</p><p>So now I'm able to post from home again, which is a bit nicer – real keyboard instead of laptop keyboard…
</p><p>I suppose the next project is going to be to sort out how to customize the appearance of the site again. Now on to what I started out to post about to begin with - </p>]]></content:encoded>
    </item>
    <item>
      <title>You don’t have to be faster than the bear</title>
      <link>https://docs.microsoft.com/archive/blogs/david_leblanc/you-dont-have-to-be-faster-than-the-bear</link>
      <pubDate>Fri, 28 May 2010 15:14:29 GMT</pubDate>
      <dc:creator><![CDATA[david_leblanc]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/david_leblanc/2010/05/28/you-dont-have-to-be-faster-than-the-bear/</guid>
      <description><![CDATA[Note – this post disappeared during the blog upgrade, recovered due to search cache.
Just got done...]]></description>
      <content:encoded><![CDATA[<p>Note – this post disappeared during the blog upgrade, recovered due to search cache.
</p><p>Just got done reading Michal Zalewski's really interesting post on the Zero Day blog, found here. 
</p><p>His premise, which I don't debate, is that we've done a lousy job of defining software security on a scholarly basis. He goes on to point out, often humorously, the flaws with many of the existing approaches. 
</p><p>My belief is that a lot of this is because we are too often computer _scientists_, and not software _engineers_. Engineering allows for failure. We don't attempt to build aircraft that cannot possibly fall out of the sky, just aircraft that don't do that very often. We have also built many aircraft where we don't have a perfect understanding of the science involved. We flew at supersonic speeds for many years before we understood the math. Even now, the Navier-Stokes equation that governs air flow (to be precise, fluids) isn't solvable in closed form – to non-mathematicians, that means we can only approximate the lift on a wing. Computers help with the problem, since numerical analysis will give better results than we did when we had to use equations and calculators or slide rules. Generally, this means we do something within some error bars. 
</p><p>Back to software security, I think it's all relative. 
</p><p><em>Given the attack tools that we have at any given moment, can a piece of software be attacked using fewer resources than the value of the resource that the software protects? If so, then it's insecure, if not, then it is good enough for now.</em>
	</p><p>That sort of squishy reasoning makes people trained in Boolean logic really uncomfortable, since in our world, everything ought to be a 0 or 1, none of this maybe stuff. 
</p><p>The core problem is that we've known for some time, dating back to the JPL studies, that there will always be some number of errors per thousand lines of code. We can get more errors with sloppy development practices, and fewer with better development practices. Even Daniel J. Bernstein makes security mistakes. 
</p><p>So a given piece of non-trivial software will always have some number of security flaws. Next problem is how much work it is to find one or more flaws – this is one of the most neglected aspects of Saltzer and Schroeder's security design principles – work factor. We then factor in what's protected by the software, and then throw in a splash of economics theory that says people will invest their time rationally in terms of perceived rewards. 
</p><p>What this boils down to is that if few people use your software, then you don't really need to put much effort into security. No one's attacking you, so vulnerabilities don't matter. Seems to be the approach of some companies out there, and this tends to be a problem if you get popular, or just annoy the attackers who then make a project out of you. 
</p><p>If a lot of people use your software, like the stuff I work on, then we should put a lot of effort into security – and we do. 
</p><p>Another point to Michal's post is that a networked system of computers is really a different problem than a fixed piece of software. If you're trying to secure a network, then it is inhabited by users and admins, both of whom inject random behaviors that we can't model well. To work with that, you need to look at what I term a security dependency analysis, where you look at the escalation paths present independently of the potential for vulnerabilities on any given node. </p>]]></content:encoded>
    </item>
  </channel>
</rss>