IEInternalshttp://blogs.msdn.com/b/ieinternals/A look at Internet Explorer from the inside out. @EricLaw left Microsoft in 2012, but was named an IE MVP in &#39;13 &amp; an IE userAgent (http://useragents.ie) in &#39;14en-USTelligent Evolution Platform Developer Build (Build: 5.6.50428.7875)Authenticode in 2015http://blogs.msdn.com/b/ieinternals/archive/2015/01/28/authenticode-in-2015-signcode-with-certificate-on-etoken.aspxWed, 28 Jan 2015 20:34:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10589430EricLaw [ex-MSFT]4http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10589430http://blogs.msdn.com/b/ieinternals/archive/2015/01/28/authenticode-in-2015-signcode-with-certificate-on-etoken.aspx#comments<p>Back in 2011, I wrote a post explaining <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/03/22/authenticode-code-signing-for-developers-for-file-downloads-building-smartscreen-application-reputation.aspx">why and how software developers should use Authenticode</a> to digitally sign their applications. While the vast majority of the original post remains relevant, in today&rsquo;s post, I&rsquo;ll share my most recent experiences with code-signing.</p>
<h2>Shopping for a Certificate</h2>
<p>In the past, I signed my code using a certificate from the Comodo Certificate Authority (CA), purchased through a popular reseller named <a href="https://author.tucows.com/">Tucows</a>. This time, I decided to shop around a bit. My first stop was <a href="https://www.globalsign.com/en/">GlobalSign</a>, but after some back and forth, I learned that they no longer sell code-signing certificates for individuals. If I wanted to get a code-signing certificate from GlobalSign, I&rsquo;d need to file formal legal paperwork with the state to register a business. Since I&rsquo;m not really making money on my freeware, I decided to keep looking.</p>
<p>My next stop was <a href="https://www.digicert.com/">DigiCert</a> and it proved more fruitful. I&rsquo;d heard a lot of good things about DigiCert because they offer <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/hh801887.aspx">discounted certificates for SysDevs</a> and free certificates for Microsoft employees and MVPs.</p>
<p>I had initially hoped to get an <a href="http://blogs.msdn.com/b/ie/archive/2012/08/14/microsoft-smartscreen-amp-extended-validation-ev-code-signing-certificates.aspx">Extended Validation Code Signing certificate</a> to ensure that my users didn&rsquo;t encounter any temporary &ldquo;Unknown Reputation&rdquo; warnings from SmartScreen Application Reputation when I first switch over to signing using the new certificate. Unfortunately, it turns out that EV Code-Signing Certificates are not available to <span style="text-decoration: underline;">individuals</span> from <em>any </em>certificate authority, so I placed an order for a regular code-signing certificate instead.</p>
<p>While it&rsquo;s unfortunate that some users might get some &ldquo;Unknown Reputation&rdquo; warnings, my software is popular enough that hopefully the reputation will build on my certificate in a few days or so. My new certificate is valid for three years, so a few days of user questions shouldn&rsquo;t prove a huge burden.</p>
<h2>Validating My Identity</h2>
<p><span style="color: #333333;">In past years, validating my identity to obtain a certificate was a complicated, multi-day affair involving faxing personal documents like my passport, utility bills, bank statements to the CA. In one case, I even had to ping the CEO of a certificate authority (we had met during my work on EV for HTTPS) to get the process unblocked.</span></p>
<p>In contrast, my experience with DigiCert was much more straightforward. I simply uploaded a copy of my driver&rsquo;s license to their secure portal, along with a scan of a notarized document containing my address, driver&rsquo;s license information, and certificate information. I was initially worried about the expense and complexity of finding a notary to countersign my document, but this turned out to be very easy. The <a href="http://www.theupsstore.com/small-business-solutions/Pages/general-business-services.aspx">UPS Store has notaries</a> on staff and they charge just $6 per page notarized; the entire process took less than 20 minutes. I've been told that some banks offer free notary services to their customers. After supplying my identity proof, I got a quick call from the CA validators and was granted permission to request a certificate.</p>
<h2>Generating a Certificate</h2>
<p><span style="color: #333333;">The DigiCert portal offers a simple push-button interface for requesting a certificate. At first, the button didn&rsquo;t work and I was reminded that, for Internet Explorer&rsquo;s <a href="http://blogs.msdn.com/b/ieinternals/archive/2010/05/14/certificate-enrollment-xenroll-vs-certenroll-activex-object.aspx">Certificate Enrollment ActiveX Control</a> to work properly, I should put the site in my Trusted Sites Zone (especially because I run in Enhanced Protected Mode). Unfortunately, even after trusting the site, I got the same error message:</span></p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2388.image_5F00_48B700F6.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="DigiCert enrollment page and Trusted Sites Zone" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4314.image_5F00_thumb_5F00_605C8F41.png" alt="DigiCert enrollment page and Trusted Sites Zone" width="644" height="314" border="0" /></a></p>
<p>Fortunately, I quickly realized the problem: I use <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/04/02/activex-control-restrictions-in-ie.aspx">ActiveX Filtering</a> to reduce my attack surface (and block annoyances) and this was preventing my use of the necessary ActiveX interface. After unblocking ActiveX controls</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="unblock ActiveX Filtering" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7080.image_5F00_637CCE0E.png" alt="unblock ActiveX Filtering" width="425" height="177" border="0" /></p>
<p>&hellip;and refreshing the page, the control loaded properly. It requested permission to generate a private key and certificate request:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="CertEnroll Prompt" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7024.image_5F00_7232CA1A.png" alt="CertEnroll Prompt" width="498" height="277" border="0" /></p>
<p>And after I chose <strong>Yes, </strong>the new certificate was generated and signed by the Certificate Authority. The new certificate is automatically placed in the <strong>Current User\Personal\Certificates </strong>store which can be found by launching <strong>CertMgr.msc </strong>or by following <a href="https://www.digicert.com/code-signing/exporting-code-signing-certificate.htm">these steps</a>.</p>
<p>Double-clicking the certificate shows the Certificate UI which confirms that Windows has the matching private key:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Private Key" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8865.image_5F00_75BF3BDC.png" alt="&quot;You have a private key&quot;" width="365" height="334" border="0" /></p>
<p>&nbsp;</p>
<h2>Exporting the Certificate</h2>
<p><span style="color: #333333;">My current build process uses <strong>signcode.exe </strong>from the Windows SDK to sign code; I supply my certificate in a SPC file and the private key in a PVK file. In order to generate these files, I must first export my certificate to a CER and a PFX file. This also allows me to back up my key, since the only copy in existence is in my Windows Certificate store.</span></p>
<p><span style="color: #333333;">Doing so is simple: just right-click the certificate and choose <strong>Export</strong>. Choose <strong>Yes, export the private key </strong>and select the <strong>Personal Information Exchange - PKCS #12 (.PFX) format</strong>. Save as </span><span style="color: #0000ff; font-family: Courier New;">mycert.pfx</span>.</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Exporting from CertMgr.msc" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1220.image_5F00_1282F3B6.png" alt="Exporting from CertMgr.msc" width="640" height="266" border="0" /></p>
<p>You&rsquo;ll be prompted for a password to protect the file: do NOT forget your choice! You should probably back up this file somewhere safe and offline (e.g. a USB drive or CD) in case your PC ever suffers from an unrecoverable problem.</p>
<p>After exporting the PFX file (which contains both the certificate and the private key) you can export a plain CER file, which contains only the certificate. In the Certificate Export Wizard, choose <strong>No, do not export the private key </strong>and choose <strong>DER encoded binary X.509 (.CER) </strong>as the format. <span style="color: #333333;">Save as </span><span style="color: #0000ff; font-family: Courier New;">mycert.cer</span>.</p>
<h2>Converting Certificate and Key Files</h2>
<p><em>Note: These steps are not always necessary, for instance if you use&nbsp;<strong>signtool&nbsp;</strong>or the&nbsp;</em><a href="https://www.digicert.com/util/"><em>DigiCert Certificate Utility</em></a><em>&nbsp;to sign your code.&nbsp;</em></p>
<p>With the CER and PFX files in hand, you now need to convert the files into SPC and PVK files used by the signing tool.</p>
<h3>PFX-&gt;PVK</h3>
<p>Unfortunately, generating the PVK file containing the private key is a little tricky. Most of the tutorials on the web suggest you download a zip file containing a converter and run it. <em>If the prospect of downloading an unsigned executable over HTTP and supplying it with your PFX and its password doesn&rsquo;t set off your internal <strong>ZOMG no!!! </strong>alarms, perhaps you&rsquo;re working in the wrong field.</em></p>
<p>So, if that approach is out, what do we do instead?</p>
<p>Here, OpenSSL comes to the rescue. First, convert to a PEM file:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: small;">openssl.exe pkcs12 -in mycert.pfx -nocerts -nodes -out mycert.pem</span></p>
<p>Then convert the PEM file to a PVK file:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: small;">openssl.exe rsa &ndash;inform pem &ndash;in mycert.pem &ndash;outform pvk -out mycert.pvk</span></p>
<p><img style="display: inline; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4265.image_5F00_06810382.png" alt="PEM to PVK" width="748" height="76" border="0" /></p>
<h3>CER-&gt;SPC</h3>
<p>Generating the SPC file from the CER is comparatively easy. Simply use the <strong>Cert2SPC.exe</strong> utility included in the Windows SDK:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: small;">cert2spc.exe mycert.cer mycert.spc</span></p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1157.image_5F00_1B065300.png"><img style="margin: 0px; display: inline; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1663.image_5F00_thumb_5F00_2F8BA27E.png" alt="image" width="741" height="36" border="0" /></a></p>
<p><em>In the unlikely event that you don&rsquo;t have the Windows SDK installed, you can generate the SPC using OpenSSL:</em></p>
<p><span style="color: #0000ff;">openssl.exe pkcs12 -in <em>mycert.pfx</em> -nokeys -out <em>mycert.pem</em> <br />openssl.exe crl2pkcs7 -nocrl -certfile <em>mycert.pem</em> -outform DER -out mycert.spc</span></p>
<h4>A word about Intermediates</h4>
<p><span style="background-color: #ffffff;">The SPC file is a serialized certificate store that contains one<em> or more</em> certificates. The Cert2SPC command line I show above includes only my code-signing certificate-- it does not include the Certificate Authority's <strong>Root Certificate</strong> or the Certificate Authority's <strong>Intermediate Certificate</strong>. In contrast, the OpenSSL command shown will include ALL certificates in the SPC file. </span></p>
<p><span style="background-color: #ffffff;">Why do we care at all? Because if it does not have the intermediate certificate, Windows must download it using the information provided in the AIA extension of the code-signing certificate. That download will obviously fail if the PC is offline, and the user will get a "Cannot verify" warning on the signature and the file will behave as if it were unsigned. If we include the intermediate in the SPC, then the verifier doesn't need to worry about downloading it. </span></p>
<p><span style="background-color: #ffffff;">However... Windows also has a feature whereby not all root certificates ship with Windows; <a href="http://netsekure.org/2011/04/automatic-ca-root-certificate-updates-on-windows/"><span style="background-color: #ffffff;">many roots are downloaded <em>on-demand</em></span></a>&nbsp;as they are encountered. So, if the end-user's computer doesn't have the necessary root installed, the signature verification logic will try to fetch it from WindowsUpdate, and if that fails because the system is offline, the user gets the same "Cannot verify" warning. As a signer, you can't simply put the root in the SPC file and avoid a network hit, however, because Windows won't trust the root until it checks with WindowsUpdate.</span></p>
<p><span style="background-color: #ffffff;">So, what to do? <strong>My recommendation is that you include the end-entity certificate and the intermediate certificate, but not the root. &nbsp;</strong>You can do this thusly: &nbsp;</span></p>
<p><span style="color: #0000ff; font-family: 'courier new', courier; font-size: small; background-color: #ffffff;">cert2spc.exe mycert.cer CAIntermediate.cer mycert.spc</span></p>
<p><span style="background-color: #ffffff;">You can get the <span style="font-family: 'courier new', courier;">CAIntermediate.cer</span> file by opening <span style="font-family: 'courier new', courier;">mycert.cer</span> in the Certificate Viewer, clicking the <strong>Certification Path</strong> tab, selecting the Intermediate node of the tree, clicking <strong>View Certificate</strong>, clicking <strong>Details</strong>, and pushing the&nbsp;<strong>Copy to File</strong> button.</span></p>
<p>You can view the contents of the SPC file by double-clicking it:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13/8666.mychain.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13/8666.mychain.png" alt="" border="0" /></a></p>
<h4>Cleanup and Backup</h4>
<div>Having completed your conversion process, you can now delete the PEM files. You should probably backup the PFX file somewhere safe (offline) before deleting it, and you should consider uninstalling your private key from the Windows Certificate store. Read on for more details.</div>
<h2>Signing Files</h2>
<p>With all files in the proper formats, you can now sign your code:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: small;">signcode -spc \src\mycert.spc -v \src\mykey.pvk -n "My App Name" -i "http://www.example.com/myApp/" -a sha1 -t http://timestamp.digicert.com MySetup.exe</span></p>
<p>I explicitly specify <strong>-a</strong> <strong>sha1</strong> for my hash algorithm, because the default algorithm (MD5) is NOT safe. I still support a few Windows XP users, and unfortunately <a href="http://blogs.msdn.com/b/ieinternals/archive/2014/09/04/personalizing-installers-using-unauthenticated-data-inside-authenticode-signed-binaries.aspx">XP doesn&rsquo;t support SHA256 for Authenticode</a>, even with Service Pack 3 installed. In another year or two, I will stop using sha1 and will use SHA256 instead.</p>
<p>I always provide a timestamp URL using the <strong>-t</strong> parameter to ensure that my program&rsquo;s signature will remain valid even after the signing certificate expires.</p>
<h1>Improving Security with Hardware</h1>
<p>As users and security software are increasingly looking for digital signatures, bad guys are now looking for ways to get their malware signed. Perhaps the simplest way for them to do so is to hack into software developers&rsquo; PCs and <a href="http://securityaffairs.co/wordpress/222/cyber-crime/avoid-control-lets-digitally-sign-malware-code.html">steal their private keys</a>, or submit their malware into automated processes <a href="http://www.cnet.com/news/adobe-to-revoke-code-signing-certificate/">configured</a> to <a href="http://arstechnica.com/security/2014/10/hp-accidentally-signed-malware-will-revoke-certificate/">sign anything they receive</a>.</p>
<p>While I&rsquo;ve never configured automatic signing of anything, I&rsquo;ve long been worried about the threat of a bad guy stealing my private key and signing his malware with my good name.</p>
<p>Fortunately, it&rsquo;s now relatively easy to raise the bar against attackers.</p>
<p>While EV-Authenticode <em>requires </em>use of a hardware token for signing, even non-EV signers like me can benefit from hardware-based signing. Below is a eToken 72K security token; this one and similar products are available online at prices ranging from a few dollars to about $40.</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4621.hardware_5F00_71FE44B4.jpg"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="hardware" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4237.hardware_5F00_thumb_5F00_51770502.jpg" alt="hardware" width="240" height="149" border="0" /></a></p>
<p>When you buy an EV code-signing certificate, you&rsquo;ll get a token with the certificate and private key installed; you <a href="https://www.digicert.com/ev-setup">don&rsquo;t need to do much</a> beyond updating the password.</p>
<p>In contrast, when you&rsquo;re setting up a token yourself, there are a few steps; my token didn&rsquo;t come with instructions, but it was pretty easy to figure out.</p>
<p>First, you need to install the appropriate software to use the token; in my case, it was the Aladdin Knowledge Systems eToken PKI client. Next, you need to know that the default password for a new eToken is <strong>1234567890</strong>. Supply this password and then pick a strong new password to replace it. Your new password should be memorable (if you forget it, you&rsquo;ll be in a world of hurt) and probably should be relatively easy to type, as you&rsquo;ll be typing it each time you sign anything.</p>
<p>In the left pane, select your token:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="EToken icon" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3247.image_5F00_65FC5480.png" alt="EToken icon" width="186" height="66" border="0" /></p>
<p><em>At first, I was a bit worried about the word &ldquo;Java&rdquo; here&mdash;was this only for signing JAR files or something? No&mdash;it&rsquo;s that the token itself is running Java for its own internal operating system.</em></p>
<p>After selecting your token at the top, click the yellow gear icon to go to <strong>Advanced View</strong>:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Advanced View Gear" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/6724.image_5F00_0853E9FA.png" alt="Advanced View Gear" width="183" height="58" border="0" /></p>
<p>You can then right-click and choose <strong>Import Certificate</strong>.</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Import Certificate menu" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8461.image_5F00_2EB5CD45.png" alt="Import Certificate menu" width="244" height="127" border="0" /></p>
<p>Since we&rsquo;ve left our certificate in the Windows Certificate Store, we&rsquo;ll choose that option:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2047.image_5F00_49EE2646.png" alt="Import Cert UI" width="426" height="239" border="0" /></p>
<p>Next comes a very confusing prompt:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/6747.image_5F00_332EDEBD.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3051.image_5F00_thumb_5F00_4094F1C3.png" alt="image" width="362" height="484" border="0" /></a></p>
<p>With fingers crossed, we click <strong>OK</strong> and get an error message:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8360.image_5F00_3BB23E07.png" alt="image" width="244" height="185" border="0" /></p>
<p><em>Hrm. </em>So we click Cancel and voila, our certificate in the Windows Certificate store appears:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3404.image_5F00_6BDC197B.png" alt="image" width="424" height="134" border="0" /></p>
<p>My guess is that the first &ldquo;Smart Card&rdquo; prompt was there in case we wanted to copy a certificate and key <em>from a different smartcard </em>to our token. When we hit Cancel, it then just shows the Windows Certificate stores. We select the desired certificate and click <strong>OK</strong>. After supplying our token&rsquo;s password, the certificate is imported.</p>
<p>After we&rsquo;ve moved the token to the token, the certificate still appears within the Windows Certificate manager (CertMgr.msc):</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1856.image_5F00_6450AA0E.png" alt="5 certs including our codesigning cert" width="491" height="125" border="0" /></p>
<p>&hellip;until we unplug the token and hit F5. At that point, the code-signing certificate disappears:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1362.image_5F00_58BAECCF.png" alt="4 Certs" width="491" height="107" border="0" /></p>
<p>Great!</p>
<h2>Signing Files From the Token</h2>
<p>Because we&rsquo;re no longer going to use the private key file from disk, we obliterate the <span style="color: #0000ff; font-family: Courier New;">mycert.pvk</span> file and update our command line as follows:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: small;">signcode <span style="color: #ff0000;">-p "eToken Base Cryptographic Provider"</span> -spc \src\mycert.spc <span style="color: #ff0000;">-k df2852d2a58a1cc5ce82d186e0fb6eda_0b960da4-1609-44a5-bfa9-aac9caea8170</span></span><span style="color: #0000ff; font-family: Courier New; font-size: small;"> -n "My App Name" -i "http://www.example.com/myApp/" -a sha1 -t http://timestamp.digicert.com MySetup.exe</span></p>
<p>We first specify that the signing should use the <strong>eToken Base Cryptographic Provider</strong>; you can find the list of available providers by looking in your registry under the <span style="font-family: Courier New;">HKLM\Software\Microsoft\Cryptography\Defaults\Provider</span> node.</p>
<p>We next replace our reference to the PVK file with the name of the container containing the private key. Fortunately, the eToken software exposes the key&rsquo;s <strong>Container name </strong>information directly in the UI:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8637.image_5F00_1B2D8F06.png" alt="Private Key Container name" width="644" height="218" border="0" /></p>
<p>Now, when we run the updated signcode command, the eToken software prompts for our password and returns the signature.</p>
<h2>Here Be Dragons</h2>
<p>At this point, I was pretty excited at how easy it was to use hardware to bolster security. For fun, I tried modifying my command line</p>
<p><span style="color: #000000;"><span style="font-size: x-small;"><span style="font-family: Courier New;">signcode -spc \src\mycert.spc -k df2852d2a58a1cc5ce82d186e0fb6eda_0b960da4-1609-44a5-bfa9-aac9caea8170</span><span style="font-family: Courier New;"> -n "My App Name" -i "http://www.example.com/myApp/" -a sha1 -t http://timestamp.digicert.com MySetup.exe</span></span></span></p>
<p>&hellip;to omit the provider directive, and signing succeeded.<em> And it didn&rsquo;t prompt me for a password.</em></p>
<p>I had a bad feeling about this.</p>
<p>I unplugged my eToken from the PC and ran the command again.</p>
<p><em>And it succeeded, without either a password or the token.</em></p>
<p><em>What the what?!?</em></p>
<p>Fortunately, I have spent a few weeks banging my head against the wall with problems with Windows Certificate Key storage in the past, and I had a theory about what was going on&mdash;perhaps the process of importing the certificate to the token <em>did</em> remove the certificate from the Windows Storage, but <em>did not</em> properly blow away the private key? (That mistake recently got a bit of press because one high-profile piece of ransomware also <a href="http://www.symantec.com/connect/blogs/cryptodefense-cryptolocker-imitator-makes-over-34000-one-month">left a copy of its RSA key locally</a>.)</p>
<p>With this hunch, I searched my <a href="https://msdn.microsoft.com/en-us/library/bb204778(VS.85).aspx">RSA keys folder</a> for any files containing the key container name:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7266.image_5F00_5D33FE47.png" alt="image" width="673" height="147" border="0" /></p>
<p>&hellip;and I got exactly one hit. After I deleted the key container file, signcode started behaving as expected: I could only sign the file using the <strong>eToken Base Cryptographic Provider </strong>and only when the token was inserted and the password supplied.</p>
<p>After having deleted my private key files (both the \Crypto\RSA\ file <em>and </em>the PVK file) from my hard disk, I ran <span style="color: #0000ff; font-family: Courier New;">cipher /w:C:\ </span>to help ensure that the key files could not be recovered in the future.</p>
<p>While I feel pretty good about my new level of security, there&rsquo;s no question that my private key would be more secure if I had been able to obtain an EV-Certificate token with a non-exportable key pre-installed.</p>
<p>Secure all the things!</p>
<p>-Eric Lawrence <br />MVP - Internet Explorer</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10589430" width="1" height="1">SecurityBest-PracticescertificateAuthenticodeIn Case You Missed Ithttp://blogs.msdn.com/b/ieinternals/archive/2015/01/27/spartan-tidbits-and-csp-rule-generator-for-fiddler.aspxTue, 27 Jan 2015 15:41:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10589024EricLaw [ex-MSFT]1http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10589024http://blogs.msdn.com/b/ieinternals/archive/2015/01/27/spartan-tidbits-and-csp-rule-generator-for-fiddler.aspx#comments<p><em>A random collection of noteworthy links:</em></p>
<p>Spartan PM Jacob Rossi wrote about <a href="http://www.smashingmagazine.com/2015/01/26/inside-microsofts-new-rendering-engine-project-spartan/">the new Project Spartan rendering engine</a>.</p>
<p>Spartan Developer Justin Rogers has a great new blog on development in general, including some <a href="http://www.justrog.com/2015/01/code-dead-code-and-undead-code.html">tantalizing</a> <a href="http://www.justrog.com/2015/01/no-variable-is-infinitely-better-than.html">posts</a> on evolving the Spartan codebase.</p>
<p>Windows 10 build 9926 has been <a href="https://insider.windows.com/">released</a>; Spartan is not yet in it, but you can enable the new EdgeHTML engine using the <strong>about:flags </strong>page; set the Experimental Flag to <strong>Enabled</strong>. Included in the build are <a href="http://blogs.msdn.com/b/ie/archive/2015/01/22/project-spartan-and-the-windows-10-january-preview-build.aspx">support for HSTS, HTTP Live Streaming, Video Tracks, DOM L3 XPath</a>, and improved developer tools make an appearance.</p>
<p>EdgeHTML includes support for <a href="https://status.modern.ie/contentsecuritypolicy">Content Security Policy</a>, a powerful technology to defang XSS and content-injection attacks. David Risney recently released a <a href="https://github.com/david-risney/CSP-Fiddler-Extension">Content Security Policy rule generator</a> extension for Fiddler. Surf your site with Fiddler running and this extension will compute the appropriate CSP rules for your site.</p>
<p>-Eric Lawrence</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10589024" width="1" height="1">SecuritystandardsSpartanHTTPS In 2015http://blogs.msdn.com/b/ieinternals/archive/2015/01/16/https-everything-in-2015-with-free-certificates-and-hsts.aspxFri, 16 Jan 2015 17:01:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10586839EricLaw [ex-MSFT]1http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10586839http://blogs.msdn.com/b/ieinternals/archive/2015/01/16/https-everything-in-2015-with-free-certificates-and-hsts.aspx#comments<p>Last week at the CodeMash conference, I delivered a session titled <a href="http://www.codemash.org/session/https-in-2015/">HTTPS in 2015</a>:</p>
<blockquote>
<p><em>Securing your websites and services using HTTPS has never been more important, or more complicated. In this talk, a former browser Security Program Manager covers the best practices for using HTTPS today. Topics covered in this session include ciphers and hash algorithms, forward secrecy, handshakes and protocols, and new browser features like HSTS and PKP. Explore how attackers circumvent HTTPS, and what you can do to help protect your visitors and customers safe from snoops and bad guys. Secure all the things!</em></p>
</blockquote>
<p>You can find the slides for my talk <a href="http://ericlawrence.com/dl/Codemash2015-ericlaw-https-in-2015.pptx">here (pptx; 4.5mb)</a> and an audio recording of the presentation <a href="http://ericlawrence.com/dl/Codemash2015-HTTPS-in-2015-64kbps.mp3">here (mp3; 30mb)</a>. During the talk, I mentioned a few topics repeatedly:</p>
<ul>
<li><a href="https://www.ssllabs.com/ssltest/">SSLLabs' Server Test</a>&nbsp;- <em>Test your server's use of HTTPS</em></li>
<li>Ivan Ristić&rsquo;s excellent <a href="https://www.feistyduck.com/books/bulletproof-ssl-and-tls/">Bulletproof SSL and TLS</a> book - <em>Understand HTTPS, attacks, and how to deploy</em></li>
<li>The <a href="https://letsencrypt.org/">Let's Encrypt Project</a></li>
</ul>
<p>The last item is perhaps the most exciting: the EFF&rsquo;s Let&rsquo;s Encrypt project is slated to offer free HTTPS certificates starting in the summer of 2015. There&rsquo;s a great summary of the project in <a href="http://media.ccc.de/browse/congress/2014/31c3_-_6397_-_en_-_saal_6_-_201412301400_-_let_s_encrypt_-_seth_schoen.html#video">this video presentation by Seth Schoen</a> from late last year.</p>
<h3>HSTS and Privacy</h3>
<p>I also wanted to take this opportunity to provide some context related to recent press about the <a href="http://arstechnica.com/security/2015/01/browsing-in-privacy-mode-super-cookies-can-track-you-anyway/">&ldquo;super-cookie attack&rdquo;</a> against HTTP Strict Transport Security.</p>
<p>In this attack, which I alluded to at the end of my <a href="http://blogs.msdn.com/b/ieinternals/archive/2014/08/18/hsts-strict-transport-security-attacks-mitigations-deployment-https.aspx">intro to HSTS post</a> last year, a site generates a large set of HSTS rules and uses these to act as a type of &ldquo;super-cookie&rdquo; identifier that can be used to uniquely identify a given client. While much of the coverage is of the breathless &ldquo;<em>Wow, so clever! Browser designers are fools!</em>&rdquo; form, the reality is that this attack has been well known since the dawn of the HSTS proposals, and it&rsquo;s even explicitly called out in the Chromium team&rsquo;s (<em>excellent</em>) <a href="http://www.chromium.org/Home/chromium-security/client-identification-mechanisms">Technical Analysis of Client Identification Mechanisms</a> document.</p>
<p>The attack vector forces browsers to make a direct tradeoff between privacy and security&mdash;ignoring HSTS decreases security, but respecting it can impact the user&rsquo;s privacy. Safari&rsquo;s approach (an undetectable, undeletable super-cookie) is clearly bad, while Chrome&rsquo;s approach (non-Incognito-set HSTS rules carry over to Incognito mode, while the reverse is not true) more carefully straddles the line.</p>
<p>It&rsquo;s not yet clear how Internet Explorer 12 will behave, leading to the following design considerations:</p>
<ol>
<li>Will IE offer a &ldquo;pre-load&rdquo; list of HSTS sites, improving security with no privacy impact?</li>
<li>Will IE allow InPrivate-set HSTS rules to apply to non-InPrivate mode?</li>
<li>Will IE allow InPrivate-set HSTS rules to apply to future InPrivate sessions?</li>
<li>Will IE allow Non-InPrivate-set HSTS rules to apply to InPrivate sessions?</li>
<li>Will deleting browser history clear all or all non-preload HSTS rules?</li>
</ol>
<p>Beyond expanding the pre-load lists, I&rsquo;m hoping that future browsers can use some additional heuristics to balance the privacy/security tradeoff. For instance, browsers could partition header-set HSTS rules by BrowsingPrivacyMode and clear them when the user dumps history, but persist any rules for sites that heuristics suggest are &ldquo;legitimate&rdquo; (e.g. the user has created a favorite, directly navigated via the address bar, etc).</p>
<h3>HTTPS Everything&nbsp;</h3>
<p>One fact is increasingly clear&mdash;moving to HTTPS is crucial to helping protect the user&rsquo;s privacy. In just one example, it&rsquo;s recently been observed that a popular <a href="https://www.eff.org/deeplinks/2015/01/verizon-and-turn-break-browser-privacy-protections">Mobile ISP is injecting a tracking identifier into all outbound HTTP request&rsquo;s</a> headers (regardless of privacy mode) and this header is being used to reconstitute cookies that users have manually deleted. Moving to HTTPS helps defeat shenanigans like this.</p>
<p>As a user: Demand HTTPS.</p>
<p>As a site: Deploy HTTPS.</p>
<p><strong>Secure all the things!</strong></p>
<p>-Eric Lawrence <br />MVP, Internet Explorer</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10586839" width="1" height="1">SecuritystandardsprivacyhttpscertificateScript Polyglotshttp://blogs.msdn.com/b/ieinternals/archive/2014/11/24/defeat-script-gif-polyglots-using-x-content-type-options.aspxMon, 24 Nov 2014 21:25:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10575682EricLaw [ex-MSFT]0http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10575682http://blogs.msdn.com/b/ieinternals/archive/2014/11/24/defeat-script-gif-polyglots-using-x-content-type-options.aspx#comments<p>Lately, there&rsquo;s been a resurgence of interest in hiding script inside files of other types; sometimes this is known as a <a href="http://www.thinkfu.com/blog/gifjavascript-polyglots">polyglot file</a>. On Twitter, there&rsquo;s been some excitement about a new tool that creates GIF/JavaScript polyglots.</p>
<p>As you can see in the example provided in the aforementioned blog, when referenced as the source of a script element, the script runs, and when referenced as the source of an img element, the GIF image renders:</p>
<p><a href="http://www.thinkfu.com/blog/gifjavascript-polyglots"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/5148.image_5F00_thumb_5F00_52330119.png" alt="image" width="349" height="293" border="0" /></a></p>
<p>&nbsp;</p>
<p>Neat. But the secret is quickly revealed if we peek at the raw bytes:</p>
<p><br /><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4405.image_5F00_1FCF2D9A.png" alt="image" width="467" height="484" border="0" /></p>
<p>As you can see, this image starts with the standard <span style="font-family: Courier New;">GIF89a</span> signature. Then, the cleverly-crafted file takes advantage of the fact that the subsequent bytes encode the size of the image. The creator specifies that the image shall be 8,253 pixels wide by 8231 tall, which is encoded using the hexadecimal values 0x203d 0x2027, which are encoded in GIFs as 3d20 and 2720 with the least significant byte first.</p>
<p>When interpreted by the JavaScript parser, these four bytes are interpreted as an equals sign, space, single quote, space. This, in turn, causes a JavaScript parser to read the file as a variable declaration, followed by more JavaScript statements, and ending with a long garbage comment.</p>
<p>So, why is this interesting? Is it a horrible security hole?</p>
<p>No, not really.</p>
<p>Back before IE8, IE would eagerly seek out HTML even inside files served as images, and as a consequence, websites that accepted user-supplied images and served those images were at risk because any HTML documents &ldquo;sniffed&rdquo; from the files would be running in the security context of the victim site. IE8 <a href="http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx">changed things</a> such that HTML would never be sniffed from files delivered with an <span style="font-family: Courier New;">image/</span> MIME type.</p>
<p>MIME-Sniffing HTML from images was much more dangerous than sniffing script, because script runs in the context of the <em>hosting </em>page, not in the context of the server that delivers the image/script. So, in order for something bad to happen today, a victim site must not only allow polyglot files to be uploaded, but <em>also </em>it must allow an attacker to inject a<span style="font-family: 'courier new', courier;"> &lt;SCRIPT SRC&gt;</span> tag into the markup that the site serves. In most cases, this is not very practical/interesting (especially because any such injection probably would be an XSS in and of itself).</p>
<p>Nevertheless, there&rsquo;s still a bit of interest here because polyglot files could conceivably be used as an attack against <a href="https://w3c.github.io/webappsec/specs/content-security-policy/">Content Security Policy</a>. Consider a CSP-protected site that decides to allow visitors to specify any <span style="font-family: 'courier new', courier;">SCRIPT SRC</span> they like, relying on CSP to ensure that the SRC attribute points to a &ldquo;safe&rdquo; server. Also, our victim site must allow image uploads to a path under the CSP-specified <span style="font-family: 'courier new', courier;">script-src</span>. With a polyglot file, the server is conceivably at risk, despite CSP.</p>
<p>There are a few best practices that help protect against attacks like this:</p>
<ol>
<li>Don&rsquo;t ever serve user-submitted content from your application&rsquo;s domain. If your application runs on <span style="font-family: Courier New;">example.com</span>, serve user-submitted content from <span style="font-family: Courier New;">example-usercontent.com</span>.</li>
<li>When specifying a CSP <span style="font-family: Courier New;">script-src</span> directive, ensure that it specifies a location where <em>only </em>known and trusted scripts reside.</li>
<li>Consider resaving (and optimizing) user-submitted image files. Reencoding image files can improve performance, privacy (dropping GPS coordinates, etc), and security (by breaking polyglots).</li>
<li>When serving user-submitted image files, serve them with the <span style="font-family: Courier New;">X-Content-Type-Options: nosniff</span> response header.</li>
</ol>
<p>The last item bears some explanation. <a href="http://blogs.msdn.com/b/ie/archive/2010/10/26/mime-handling-changes-in-internet-explorer.aspx">Back in IE9</a>, the MIME-Sniffing logic was improved such that a SCRIPT element whose response bore the nosniff directive would be rejected if the MIME type does not match one of the following values <span style="font-family: Courier New;">["text/javascript", "application/javascript", "text/ecmascript", "application/ecmascript", "text/x-javascript", "application/x-javascript", "text/jscript", "text/vbscript", "text/vbs"]</span>. This protection was added to help protect against other types of attacks (specifically, the leaking of cross-origin information in JavaScript error objects) but it&rsquo;s useful here as well.</p>
<p>We can add this response header using Fiddler's Filters tab to prototype the effect. As you can see below, Chrome 39 also supports the <span style="font-family: Courier New;">nosniff</span> directive, but Firefox 36 does not:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/0753.image_5F00_5C86B62A.png" alt="image" width="644" height="388" border="0" /></p>
<p>&nbsp;</p>
<p>As far-fetched as the attack scenario may be, it still may make sense for browser vendors to require a proper MIME type on any SCRIPT response when CSP is in use. They might even want to broaden the existing logic such that <span style="font-family: Courier New;">image/ </span>responses can never be used as anything other than an image.</p>
<p>-Eric Lawrence <br />MVP, Internet Explorer</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10575682" width="1" height="1">SecurityBest-PracticesBetterInIE9Compressing the Webhttp://blogs.msdn.com/b/ieinternals/archive/2014/10/21/http-compression-optimize-file-formats-with-deflate.aspxTue, 21 Oct 2014 21:11:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10566360EricLaw [ex-MSFT]4http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10566360http://blogs.msdn.com/b/ieinternals/archive/2014/10/21/http-compression-optimize-file-formats-with-deflate.aspx#comments<p><em>Be succinct.</em></p>
<p>Virtually any network-based application can be made faster by optimizing the number of bytes transferred across the network. Taking advantage of <a href="http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx">caching</a> is a great way to minimize transfer sizes, but just as important is to reduce the size of the resources you transfer.</p>
<p>Data compression is used throughout the protocols and formats used by browsers, and today&rsquo;s post is a summary of where you can find compression in use and how you can optimize it to improve the performance of your sites and services.</p>
<h2>Compression Categories</h2>
<p>Conceptually, compression is simple: recognize patterns in data and reduce repetition to minimize the size of the data. There are two major categories of compression: <strong>lossy </strong>and <strong>lossless</strong>.</p>
<p>When information is compressed with lossy compression, reversing the process (decompression) doesn&rsquo;t result in the original data, but instead a surrogate which resembles the original either closely or loosely depending on the <em>quality </em>of the compression. In browsers, the primary uses of lossy compression are in the JPEG image file format, the MP3 audio file format, and the MPEG video file format. These formats utilize understanding of human perception to drop details that are unlikely to be noticed by the viewer/listener, resulting in often-huge savings in data size. While important, this post won&rsquo;t discuss lossy compression any further.</p>
<p>In contrast, decompressing data that was losslessly compressed results in an <em>exact</em> copy of the original data&mdash;every byte is identical. Lossless compression is used throughout the web platform, in both the HTTP layer and internally within many web file formats including PNG, PDF, SWF, WOFF, and many more. The remainder of this post explores the use and optimization of lossless compression.</p>
<h3>HTTP Headers</h3>
<p>HTTP requests advertise the decompression algorithms the client supports using the<strong> <span style="font-family: Courier New;">Accept-Encoding</span></strong> request header.</p>
<p>Servers indicate which compression algorithm was used for a given response using the <strong>Content-Encoding </strong>response header. Unfortunately, even the updated HTTP/1.1 specification <a href="http://tools.ietf.org/html/rfc7230#section-4">implies</a> that servers can use compression-related tokens in the <span style="font-family: Courier New;">Transfer-Encoding</span><strong> </strong>response header, but indicating compression using<strong> the Transfer-Encoding header</strong>&nbsp;<strong>does not work </strong>in any major browser (all support only the <span style="font-family: Courier New;">chunked</span> token).</p>
<p>If the server utilizes compression, it should generally include a <span style="font-family: Courier New;">Vary: Accept-Encoding</span> response header to help ensure that a cache does not <a href="http://blogs.msdn.com/b/ieinternals/archive/2009/06/17/vary-header-prevents-caching-in-ie.aspx">mistakenly serve a compressed response</a> to a client that cannot understand it.</p>
<h2>Algorithms</h2>
<p>The most popular compression algorithm in use on the web is the DEFLATE algorithm, specified in <a href="https://www.ietf.org/rfc/rfc1951.txt">RFC 1951</a>. DEFLATE combines the <a href="http://en.wikipedia.org/wiki/LZ77_and_LZ78">LZ77</a> algorithm with Huffman encoding; it is straightforward to implement and effectively compresses a wide variety of data types. You can read a straightforward explanation of the algorithm <a href="http://www.zlib.net/feldspar.html">here</a>, and watch a fun video showing how repeated byte sequences are referenced <a href="https://www.youtube.com/watch?v=SWBkneyTyPU">here</a>.</p>
<p>In browsers, the most obvious use of the DEFLATE algorithm is for <a href="http://tools.ietf.org/html/rfc7230#section-4.2">HTTP/1.1</a> Content-Encoding. DEFLATE is the algorithm underlying two of the three encodings defined in the HTTP specification (&ldquo;<span style="font-family: Courier New;">Content-Encoding: gzip</span>&rdquo; and &ldquo;<span style="font-family: Courier New;">Content-Encoding: deflate</span>&rdquo;).</p>
<h3>DEFLATE vs. GZIP for Content-Encoding?</h3>
<p>Given that virtually all clients allow both &ldquo;<span style="font-family: Courier New;">Content-Encoding: gzip</span>&rdquo; and &ldquo;<span style="font-family: Courier New;">Content-Encoding: deflate</span>&rdquo;, which should you use?</p>
<p>You&rsquo;ll find conflicting opinions on the topic, many of which are written without the understanding that both encodings are based on exactly the same algorithm, and the encodings differ only in the header and trailer bytes that wrap the compressed data.</p>
<p>The <a href="http://tools.ietf.org/html/rfc1952">GZIP encoding</a> of a resource starts with two magic bytes <span style="font-family: Courier New;">0x1F 0x8B</span>, a byte representing the compression method (<span style="font-family: Courier New;">0x08</span>, indicating DEFLATE), seven additional bytes of metadata, several optional fields (rarely used), and then the DEFLATE-compressed bytes. After the compressed data, a 32bit <a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC-32</a> and 32bit original datasize field complete the format.</p>
<p>Despite its name, the DEFLATE encoding of a resource is <em>specified</em> to be the <a href="http://tools.ietf.org/html/rfc1950">ZLIB data format</a>. This format consists of two header bytes; the first contains the compression method and window-size information (the low bits of the byte are <span style="font-family: Courier New;">0x08</span>, indicating DEFLATE). The second header byte is a flag byte which indicates the compression strategy (minimize size vs. maximize speed) and serves as a checksum of the header bytes. The DEFLATE-compressed bytes follow. After the compressed data, a 32-bit <a href="http://en.wikipedia.org/wiki/Adler-32">ADLER32</a> checksum field completes the format.</p>
<p>So, all other things being equal,<strong> </strong>a <span style="font-family: Courier New;">C-E:GZIP</span>-encoded resource will be exactly 11 bytes bigger than a <span style="font-family: Courier New;">C-E:DEFLATE</span>-encoded resource, due to the seven additional header bytes and four additional trailer bytes. In practice, however, your compression program may generate wildly different results.</p>
<p>Now, note that I said the encoding is <em>specified to be the ZLIB data format</em>. Here&rsquo;s what you&rsquo;ll see in Internet Explorer if you try to load a page which has the ZLIB-wrapper around the DEFLATE data:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3036.image_5F00_45185D80.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3652.image_5F00_thumb_5F00_023C1906.png" alt="image" width="739" height="391" border="0" /></a></p>
<p>The problem is that <a href="https://connect.microsoft.com/IE/feedback/details/1007412/interop-wininet-does-not-support-content-encoding-deflate-properly">Internet Explorer expects a bare DEFLATE stream</a> without the ZLIB wrapper bytes. So, does that mean you can&rsquo;t use <span style="font-family: Courier New;">Content-Encoding: deflate</span>? Not really, no. In addition to supporting the proper ZLIB-wrapped data, Chrome, Firefox, Safari, and Opera all support bare DEFLATE.</p>
<p>Some folks recommend you <a href="http://zoompf.com/blog/2012/02/lose-the-wait-http-compression">avoid C-E:Deflate</a> and just stick with C-E:GZIP. It&rsquo;s hard to argue with that approach.</p>
<h3>Optimizing DEFLATE</h3>
<p>No matter which DEFLATE-based Content-Encoding you choose, the quality of the implementation underlying DEFLATE implementation is key to reducing the size of the data stream. Many developers mistakenly assume that &ldquo;DEFLATE is DEFLATE&rdquo;, and any compressor that implements the algorithm will get the same result. This is a mistake.</p>
<p>Instead, think of DEFLATE&rsquo;ing as solving a maze. <a href="http://commons.wikimedia.org/wiki/File:MAZE.png">A really really complicated maze</a>. You might run around as fast as you can and eventually stumble upon an exit, but that&rsquo;s very different than finding the optimal path. If you instead spent much longer, frequently retracing your steps to find out whether there&rsquo;s a shortcut you missed, you may find a much shorter path. DEFLATE works much the same way&mdash;you can expend more resources (CPU time and memory) in the compression process finding the optimal compression choices. The best part is that expending resources to optimize DEFLATE compression doesn&rsquo;t typically increase <em>decompression </em>time&mdash;uncompressing DEFLATEd content is a comparatively straightforward process.</p>
<p>For static resources that will be reused often (think of jQuery.js and other frameworks) you should be delighted to trade a one-time compression cost for a millions-of-times transfer size savings. Fortunately, folks at Google have done the hard work of making a great DEFLATE implementation, called <a href="http://code.google.com/p/zopfli/">Zopfli</a>&nbsp;(pronounced "zopflee"); you can read more about it and its real-world savings over <a href="http://blogs.telerik.com/fiddler/posts/14-07-02/maximize-compression-with-zopfli">here</a>. Unfortunately, far too few teams have integrated Zopfli into their workflow; even Google hasn&rsquo;t gotten around to using it for most of their resources&hellip; yet.</p>
<p>If Microsoft were to use Zopfli when building the browser-based versions of Office, they&rsquo;d see significant savings; three of their largest files shrink by just over 4% each:</p>
<table style="width: 399px;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="94"><strong>File</strong></td>
<td valign="top" width="96">Original Size</td>
<td valign="top" width="76">Served (gzip) Size</td>
<td valign="top" width="76">Zopfli Size</td>
<td valign="top" width="55">Savings</td>
</tr>
<tr>
<td valign="top" width="94">WordViewer.js</td>
<td valign="top" width="96">661,771</td>
<td valign="top" width="76">171,189</td>
<td valign="top" width="76">164,272</td>
<td valign="top" width="55">4%</td>
</tr>
<tr>
<td valign="top" width="94">Ewa.js</td>
<td valign="top" width="96">729,547</td>
<td valign="top" width="76">202,400</td>
<td valign="top" width="76">193,822</td>
<td valign="top" width="55">4.2%</td>
</tr>
<tr>
<td valign="top" width="94">WordEditor.js</td>
<td valign="top" width="96">1,876,196</td>
<td valign="top" width="78">482,125</td>
<td valign="top" width="80">462,147</td>
<td valign="top" width="68">4.1%</td>
</tr>
</tbody>
</table>
<p>Of course, you won&rsquo;t always be able to use Zopfli to compress your resources&mdash;the compression tradeoff isn&rsquo;t appropriate for dynamically-generated responses which will only be served once. But you can use it for more than just your HTML, CSS, and JS. Read on for more details.</p>
<h3>Exotic Encodings</h3>
<p>One of the <a href="http://code.google.com/p/zopfli/issues/detail?id=6&amp;can=1">first criticisms of Zopfli</a> was &ldquo;<em>it seems like an awful lot of effort for a small improvement. Perhaps it&rsquo;s time to add a better compression method</em>.&rdquo; And this criticism is valid to a certain extent.</p>
<h4>bzip2</h4>
<p>For instance, the first versions of Google Chrome added support for <a href="http://en.wikipedia.org/wiki/Bzip2">bzip2</a> as a HTTP Content-Encoding, because (quoting a Google engineer) &ldquo;well, we had the code laying around." Bzip2 yields much better compression than even Zopfli-optimized DEFLATE:</p>
<table style="width: 353px;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="128"><strong>File</strong></td>
<td valign="top" width="85">Zopfli Size</td>
<td valign="top" width="61">BZIP2 Size</td>
<td valign="top" width="77">Savings</td>
</tr>
<tr>
<td valign="top" width="128">WordViewer.js</td>
<td valign="top" width="85">164,272</td>
<td valign="top" width="61">139,393</td>
<td valign="top" width="77">15.1%</td>
</tr>
<tr>
<td valign="top" width="128">Ewa.js</td>
<td valign="top" width="85">193,822</td>
<td valign="top" width="61">163,204</td>
<td valign="top" width="77">15.8%</td>
</tr>
<tr>
<td valign="top" width="128">WordEditor.js</td>
<td valign="top" width="90">462,147</td>
<td valign="top" width="74">396,897</td>
<td valign="top" width="89">14.1%</td>
</tr>
</tbody>
</table>
<p>And bzip2 doesn&rsquo;t even offer the highest compression ratios: lzma2 showed even better results when we looked at it back in the IE9 timeframe.</p>
<p>The challenge with more advanced compression schemes is that there are <strong>billions of clients </strong>that support DEFLATE-based schemes, and as we&rsquo;ve seen previously, most implementations haven&rsquo;t yet optimized their use of DEFLATE. Making matters worse are <strong>intermediaries</strong>: Google reportedly encountered network proxies and security applications that would corrupt bzip2-encoded traffic.</p>
<h4>Xpress</h4>
<p>Some Microsoft products (Exchange, Software Update Services, etc) use <span style="font-family: Courier New;">Content-Encoding: xpress</span>, a scheme based on LZ77 (like DEFLATE), optimized for compression speed. <a href="http://msdn.microsoft.com/en-us/library/hh554002.aspx">Xpress encoding</a> is not used by Internet Explorer, WinINET, WinHTTP, or System.NET, the dominant HTTP implementations on Windows. When run on Windows 8 or later, Fiddler can decompress Xpress-encoded content using the native libraries.</p>
<h4>SCDH</h4>
<p>Back in 2008, Google <a href="http://lists.w3.org/Archives/Public/ietf-http-wg/2008JulSep/att-0441/Shared_Dictionary_Compression_over_HTTP.pdf">proposed</a> the SCDH (Shared Dictionary Compression over HTTP) Content-Encoding, and support has subsequently been added to Chrome and Android. Despite offering large potential savings, this lossless compression scheme is not broadly used and is comparatively complex to implement. It also has <a href="https://sites.google.com/a/chromium.org/dev/Home/chromium-security/client-identification-mechanisms#TOC-SDCH-dictionaries">privacy implications</a>.</p>
<h4>Compress</h4>
<p>The only non-DEFLATE-based HTTP-specification defined encoding (&ldquo;<span style="font-family: Courier New;">Content-Encoding: compress</span>&rdquo;) is based on the <a href="http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch">LZW compression algorithm</a>. Compress is not broadly supported (it doesn&rsquo;t work in any major browser) and a quick test suggests that it&rsquo;s not even as effective as a basic DEFLATE encoder.</p>
<h2>What Gets Compressed</h2>
<p>In general, HTTP Content-Encoding based compression applies to only the <strong>response body</strong>. This means that <strong>HTTP</strong> <strong>headers</strong> are not compressed, a significant shortcoming in the compression scheme. For instance, I recently observed Facebook delivering a 49 byte GIF file with 1050 bytes of HTTP headers, an overhead of over 2000% for a single file. Similarly, Content-Encoding is rarely applied to <strong>request</strong> bodies.</p>
<h3>TLS Compression</h3>
<p>When negotiating a HTTPS connection, the client may indicate support for automatic compression of all data on the connection, which has the benefit of applying to both headers and bodies of both the request and the response. TLS-based compression was not broadly implemented (Microsoft products have never supported it) and in 2012 it was disabled entirely by major products to address an exploit called <a href="http://en.wikipedia.org/wiki/CRIME">CRIME</a> (Compression Ratio Info-leak Made Easy).</p>
<h3>HTTP/2 Compression</h3>
<p>The <a href="https://tools.ietf.org/html/draft-ietf-httpbis-http2-14">HTTP/2 draft 14</a> enables header compression using an algorithm called <a href="https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09">HPACK</a>, designed to combat the CRIME exploit against the <a href="http://www.chromium.org/spdy/spdy-whitepaperhttp://www.chromium.org/spdy/spdy-whitepaper">SPDY</a> protocol (which used DEFLATE to compress header fields). Draft 12 of the specification removed per-frame GZIP compression for data; you&rsquo;ll still use <span style="font-family: Courier New;">Content-Encoding</span>.</p>
<h3>Compressing WebSocket Data</h3>
<p>Check out <a href="https://www.igvita.com/2013/11/27/configuring-and-optimizing-websocket-compression/">https://www.igvita.com/2013/11/27/configuring-and-optimizing-websocket-compression/</a> for discussion of a mechanism to use DEFLATE to compress data sent over WebSockets.</p>
<h3>Compressing Request Bodies</h3>
<p>In theory, HTTP allows clients to compress request bodies using the same <span style="font-family: Courier New;">Content-Encoding</span> mechanism used for HTTP responses. In practice, however, this feature is not used by browsers and is only rarely used by other types of HTTP clients.</p>
<p>One problem is that a client does not know, a priori, whether a server accepts compressed requests. In contrast, a server knows whether a client accepts compressed responses by examining the <span style="font-family: Courier New;">Accept-Encoding</span> request header. Many servers do not accept compressed requests, although some have no objection (e.g. onedrive.live.com allows them). One consequence of this is that HTML forms do not (yet?) expose any way for authors to specify that compression of the request body should be undertaken.</p>
<p>Modern web applications can workaround the shortcomings in browser APIs with script:</p>
<ol>
<li>Use HTML5 File API to load a file for upload into JavaScript</li>
<li>Compress it using a script-based compression engine (of many, <a href="https://github.com/nodeca/pako">Pako</a> and <a href="https://github.com/cscott/compressjs">compressjs</a> look nice)</li>
<li>Upload the compressed array to the server.</li>
</ol>
<p>You can use Fiddler to see whether your server accepts request bodies with <span style="font-family: Courier New;">Content-Encoding</span>; click Rules &gt; Customize Rules. Scroll to <strong>OnBeforeRequest </strong>and add the following code inside the function:&nbsp;&nbsp;&nbsp;</p>
<p><span style="color: #0000ff; font-family: Lucida Console; font-size: x-small;">&nbsp; if (oSession.HTTPMethodIs("POST")) <br />&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp; oSession["ui-backcolor"] = "yellow"; <br />&nbsp;&nbsp;&nbsp;&nbsp; oSession.utilGZIPRequest();&nbsp;&nbsp; <br />&nbsp;&nbsp; }</span></p>
<p>If the server accepts the upload, you should see a normal HTTP/200 response (although you may wish to ensure that the server properly recognized the compression and didn&rsquo;t just treat it like binary garbage). If the server doesn&rsquo;t accept compressed uploads, you will likely see a HTTP/400 or HTTP/500 error code.</p>
<h4>Compression Bombs</h4>
<p>One reason that servers might be reluctant to support compressed uploads is the fear of &ldquo;<a href="http://en.wikipedia.org/wiki/Zip_bomb">Compression bombs</a>&rdquo;. The DEFLATE algorithm allows a peak compression ratio approaching <a href="http://security.stackexchange.com/questions/51071/zlib-deflate-decompression-bomb">1032 to 1</a>, so a one megabyte upload can explode to 1 gigabyte. Such attacks are generally possible against client applications like browsers, but tend to be much more potent against servers, where a single CPU is required to serve thousands of users simultaneously.</p>
<p>Protecting against maliciously crafted compression streams requires additional diligence on the part of implementers.</p>
<h2><strong>Best Practice: Minify, then Compress</strong></h2>
<p>Because DEFLATE yields such great reductions in size, you might be thinking &ldquo;<em>I don&rsquo;t need to minify my assets. I can just serve them compressed</em>.&rdquo;</p>
<p>From a networking point of view, you&rsquo;re mostly correct: the bytes-on-wire for Minify+DEFLATE will likely be nearly the same as DEFLATE alone. However, there are other concerns:</p>
<p><strong>Memory</strong>: The browser must decompress your stylesheets, script, and HTML to strings, so a 50kb script file, compressed to 5kb, still uses 50kb of memory after it has been decompressed. If you can minify the script to 40kb before compressing, you can save at least 10kb of memory on the client (and likely more). This is particularly important on memory-constrained mobile devices.</p>
<p><strong>Disk Cache: </strong>Some browsers store compressed responses in the cache in compressed form (and Firefox will even proactively compress uncompressed responses). However, Internet Explorer removes all Content-Encoding when writing to the cache file, meaning that your 50kb script file will occupy 50kb of the client&rsquo;s cache. Smaller files will reload faster and are less enticing candidates for eviction when cache space is reclaimed.</p>
<h2>File Formats</h2>
<p>As mentioned previously, many file formats internally use DEFLATE compression; a great example is the <a href="http://www.w3.org/TR/PNG/">PNG image format</a>. Unfortunately, many generators of those formats opt for minimum compression time, failing to achieve maximum compression.</p>
<p>Fiddler now includes&nbsp;<strong>PNGDistill</strong>, a simple tool that removes unnecessary metadata chunks and recompresses image data streams using Zopfli. Zopfli-based recompression often shaves 10% or more from the size of PNG files. You can access this tool from the context menu of the ImageView inspector:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3005.image_5F00_763A28D1.png"><img style="display: inline; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7242.image_5F00_thumb_5F00_05DCC494.png" alt="image" width="644" height="235" border="0" /></a></p>
<p>The &ldquo;Minify-then-compress&rdquo; Best Practice applies to image file types as well. While large fields of empty pixels compress really well, the browser must decompress those fields back into memory. So, if you're building a sprite image with all of your site's icons, don't leave a huge empty area in it.</p>
<p>Beyond PNG, the WOFF font format also uses DEFLATE. Google recently shrank their WOFF font library <a href="https://plus.google.com/+IlyaGrigorik/posts/1sxencNkbNS">by an average of 6%</a> by reencoding their internal DEFLATE streams using Zopfli. Not content to stop there, Google has also introduced the WOFF2 format, which utilizes an innovative&nbsp;new&nbsp;algorithm known as <a href="http://tools.ietf.org/html/draft-alakuijala-brotli-01">Brotli</a>, yielding <a href="http://www.w3.org/TR/WOFF20ER/#lzma-size">size reductions around 20%</a>&nbsp;over WOFF. WOFF2 is currently usable in Chrome, Opera, and Firefox dev builds; see <a href="http://caniuse.com/#search=woff2">CanIUse.com</a>&nbsp;and <a href="https://status.modern.ie/wofffileformat20?term=woff%20file">status.modern.ie</a>.</p>
<h2>Compression-Related Trivia</h2>
<p><em>Here are a few points of compression-related arcana that have come up over the years&hellip;</em></p>
<p>1. The HTTP decompression implementation used by Internet Explorer 6 and earlier was inside URLMon; the WinINET HTTP stack did not itself support decompression. As a consequence, there was a &ldquo;dance&rdquo; whereby WinINET would download the compressed version and ask URLMon to decompress the response in place, replacing the original compressed body. This &ldquo;dance&rdquo; was buggy in many corner cases, and led to problems where content could not be decompressed, or Vary headers were ignored, or similar.</p>
<p>In Internet Explorer 7, decompression was moved from URLMon down into WinINET, eliminating the &ldquo;dance&rdquo; and slaying many bugs.</p>
<p>2. Unfortunately, the fact that decompression happens so low in the stack causes its own minor problems, like the <a href="https://connect.microsoft.com/IE/Feedback/Details/812445">F12 Developer Tools not being aware of the use of Content-Encoding</a>.</p>
<p>3. Some Apache servers will mistakenly serve <span style="font-family: Courier New;">.tar.gz</span> files with a <span style="font-family: Courier New;">Content-Encoding: gzip</span> header, leading the browser to eagerly decompress the downloaded file into a raw tar file with now-misleading filename extension. Firefox works around this issue by ignoring the <span style="font-family: Courier New;">Content-Encoding</span> header if the response Content-Type is <span style="font-family: Courier New;">application/x-gzip</span>. Internet Explorer 11 recently and briefly had a <a href="https://connect.microsoft.com/IE/Feedback/Details/950689">regression in its handling</a> of related scenarios.</p>
<p>4. Despite the fact that the GZIP footer includes a CRC32 and OriginalSize field to enable detection of corruption, <a href="https://code.google.com/p/chromium/issues/detail?id=161127#c17">no browser complains</a> if these fields are incorrect or missing entirely&nbsp;(which makes some sense, insofar as the original requester has already read the entire response before these fields are available). But you should set these correctly, or various tools and&nbsp;middleware might reject your content.</p>
<p>5. Even worse, a small number of servers apparently fail to <a href="http://daniel.haxx.se/blog/2014/10/26/stricter-http-1-1-framing-good-bye/">update the HTTP Content-Length header</a> when compressing the body.</p>
<p>-Eric Lawrence<br />MVP, Internet Explorer</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10566360" width="1" height="1">performancecachinghttpstandardsbugsinteropNew Microsoft Message Analyzer Releasedhttp://blogs.msdn.com/b/ieinternals/archive/2014/09/16/microsoft-message-analyzer-updated-_2D00_-capture-low-level-network-traces.aspxTue, 16 Sep 2014 20:19:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10558397EricLaw [ex-MSFT]0http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10558397http://blogs.msdn.com/b/ieinternals/archive/2014/09/16/microsoft-message-analyzer-updated-_2D00_-capture-low-level-network-traces.aspx#comments<p>If you want to monitor extremely low-level network traffic (e.g. TCP/IP packet flags, HTTPS alert records, etc), then <a href="http://fiddler2.com/">Fiddler</a> typically cannot help you; you will need to use a packet capture tool like Wireshark or Microsoft&rsquo;s Network Monitor (old) or Message Analyzer (new).</p>
<p>Yesterday, Microsoft released the newest version of Microsoft Message Analyzer (v1.1), which offers packet capture as well as more exotic capture types (ETW, etc). You can read the announcement and download from here: <a title="http://blogs.technet.com/b/messageanalyzer/archive/2014/09/15/announcing-the-message-analyzer-1-1-release.aspx" href="http://blogs.technet.com/b/messageanalyzer/archive/2014/09/15/announcing-the-message-analyzer-1-1-release.aspx">http://blogs.technet.com/b/messageanalyzer/archive/2014/09/15/announcing-the-message-analyzer-1-1-release.aspx</a>.</p>
<p>Note: If someone else happens to send you a Message Analyzer capture in <span style="font-family: Courier New;">.cap</span> format, you can extract any HTTP traffic from it into Fiddler by choosing File &gt; Import &gt; Packet Capture.</p>
<p>-Eric Lawrence <br />MVP, Internet Explorer</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10558397" width="1" height="1">networkingCaveats for Authenticode Code Signinghttp://blogs.msdn.com/b/ieinternals/archive/2014/09/04/personalizing-installers-using-unauthenticated-data-inside-authenticode-signed-binaries.aspxThu, 04 Sep 2014 19:14:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10555164EricLaw [ex-MSFT]5http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10555164http://blogs.msdn.com/b/ieinternals/archive/2014/09/04/personalizing-installers-using-unauthenticated-data-inside-authenticode-signed-binaries.aspx#comments<p>Back in 2011, I wrote a <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/03/22/authenticode-code-signing-for-developers-for-file-downloads-building-smartscreen-application-reputation.aspx">long post about Authenticode</a>, Microsoft&rsquo;s Code Signing technology. In that post, I noted:</p>
<blockquote>
<p><span style="color: #666666;">Digitally signing your code helps to ensure that it cannot be tampered with, either on your servers, or when it is being downloaded to a user&rsquo;s computer, especially over an insecure protocol like HTTP or FTP. This provides the user the confidence of knowing that the program they&rsquo;ve just downloaded is the same one that you built.</span></p>
</blockquote>
<p>This summary is mostly correct, but it oversimplifies things a bit. In this post, we&rsquo;ll take a deep dive into Authenticode to show that things aren&rsquo;t quite as simple as they might appear.</p>
<h1>Personalized Installers</h1>
<p>Say you&rsquo;re a service like Copilot, Dropbox, or GoToMeeting. Each of these services has a website and a client application that users download to interact with the service. However, unlike many traditional applications, each of these downloadable applications is meant to be personalized to an individual user; for instance, Copilot wants the application to connect to the remote assistance session without any prompts, GoToMeeting wants the user to immediately join an in-progress conference, and Dropbox wants their app to immediately begin syncing files to the user&rsquo;s cloud account.</p>
<p>Each of these services is security-conscious, so they sign their installers with Authenticode to prevent tampering and to ensure that users have a painless install experience.</p>
<p>However, the use of Authenticode makes installer personalization tricky. There are three approaches:</p>
<ol>
<li>Have the installer attempt to detect the user by groveling data from browsers</li>
<li>Dynamically generate and sign a new installer each user upon download</li>
<li>&ldquo;Cheat&rdquo; -- Find some way to use one Authenticode signature for multiple different installers</li>
</ol>
<p>&nbsp;</p>
<h3>Browser Groveling</h3>
<p>Approach #1 is tricky: there are at least three popular browsers on Windows (Chrome, Firefox, and Internet Explorer). Of those, only Internet Explorer offers a standard published API for native code applications to retrieve cookies or cached data. And unfortunately, Protected Mode and <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx">Enhanced Protected Mode</a> made things much harder.</p>
<p>Prior to the introduction of Protected Mode, an application could simply call <a href="http://msdn.microsoft.com/en-us/library/aa384714(VS.85).aspx">InternetGetCookieEx</a> and grab Internet Explorer&rsquo;s cookie for the service&rsquo;s website. However, that API doesn&rsquo;t work to grab Protected Mode cookies, and the replacement API (<a href="http://msdn.microsoft.com/en-us/library/cc196998(VS.85).aspx">IEGetProtectedModeCookie</a>) doesn&rsquo;t work if the calling process is running as Administrator, which many installers do. And if the user is using the Windows 8 &ldquo;Immersive IE&rdquo; or manually enabled Enhanced Protected Mode, there&rsquo;s <em>no </em>API available to get the cookie at all.</p>
<p>While the &ldquo;Browser Groveling&rdquo; approach was once popular (it&rsquo;s why the IEGetProtectedModeCookie API was created to begin with), it probably isn&rsquo;t used very often these days.</p>
<h3>Dynamic Generation and Signing</h3>
<p>Approach #2 is conceptually simple: every time you get a download request, a server-side process prepares a custom version of the installer executable (say, by replacing a reserved block of null bytes with a token) and then signs the resulting program.</p>
<p>On one hand, this is quite straightforward, but it might be computationally expensive to generate a new installer and signature on every single download. Furthermore, using this approach requires careful attention to security: it would be insanely risky to put the code-signing private key on the web server and have that server do the work; you&rsquo;ll want to have the frontend web server invoke a backend service running on a different machine to do the generation and signing.</p>
<p>The Copilot.com installer appears to make use of this architecture.</p>
<h3>Cheating Authenticode</h3>
<p>Approach #3 seems either silly or crazy&mdash;if the whole point of using Authenticode is to ensure the integrity of the code, then there shouldn&rsquo;t be any way around that, right?</p>
<p>The devil, as always, is in the details.</p>
<blockquote>
<p><span style="font-family: Courier New;">using Authenticode is to ensure the integrity <strong><span style="text-decoration: underline;">of the code</span></strong></span></p>
</blockquote>
<p>Authenticode indeed verifies the integrity of the <em>code</em>. But the code doesn&rsquo;t make up the entire downloaded executable.</p>
<p>Microsoft helpfully publishes the <a href="http://msdn.microsoft.com/en-us/gg463180.aspx">Windows Authenticode Portable Executable Signature Format</a> (and the less relevant <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx">Microsoft PE and COFF Specification</a>) document, which outlines in great detail how Authenticode works.</p>
<p>The first document includes this very helpful map:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7178.image_5F00_0B1DFFAD.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/6445.image_5F00_thumb_5F00_210771FD.png" alt="image" width="375" height="484" border="0" /></a></p>
<p>Items marked with a grey background aren&rsquo;t included in the signed hash; the latter two grey blocks come from the signature itself, and the injection of the signature changes the file&rsquo;s embedded checksum which is recomputed.</p>
<p>So, this all looks good, right? The signer is hashing everything in the file except for the bits related to the signature itself.</p>
<p>And there&rsquo;s the rub&mdash;the signature blocks themselves can contain data. This data isn&rsquo;t validated by the hash verification process, and while it isn&rsquo;t <em>code </em>per-se, an executable with such data could examine itself, find the data, and make use of it.</p>
<h4>WIN_CERTIFICATE Structure Padding</h4>
<p>The first place that sneaky developers found to shove additional data is after the <a href="http://tools.ietf.org/html/rfc2315">PKCS#7-formatted data</a>. The WIN_CERTIFICATE structure has a length field which specifies how many bytes will be used to hold certificate data; this value can be larger than the number of bytes used by the certificate data.</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1754.image_5F00_459B9032.png" alt="image" width="330" height="99" border="0" /></p>
<p>MVP Didier Stevens wrote a great <a href="http://blog.didierstevens.com/2013/08/13/a-bit-more-than-a-signature/">blog post</a> describing this technique and offering a <a href="http://blog.didierstevens.com/programs/authenticode-tools/">downloadable tool (with source)</a> that allows you to explore whether there is additional data stored after the embedded certificates.</p>
<p>For instance, you can see this trick used to embed tracking data in an <a href="http://sourceforge.net/projects/chrome-offline/?source=typ_redirect">old &ldquo;offline installer&rdquo; for Chrome:</a></p>
<p align="center">&nbsp;<img style="display: inline; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7853.image_5F00_32E6967B.png" alt="image" width="345" height="40" border="0" /></p>
<p align="center"><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3240.image6_5F00_209DCFB9.png"><img style="display: inline; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/0045.image6_5F00_thumb_5F00_5BF13577.png" alt="image" width="404" height="73" border="0" /></a></p>
<p align="left">In December 2013, <a href="http://blogs.technet.com/b/srd/archive/2013/12/10/ms13-098-update-to-enhance-the-security-of-authenticode.aspx">Microsoft announced</a> that some developers had foolishly used this trick to store URLs of code that would be downloaded and installed by a signed &ldquo;stub&rdquo; installer. The bad guys noticed that they could edit these &ldquo;stub&rdquo; installers, changing the embedded URLs to point to malware, and the signature of the stub wouldn&rsquo;t change. The file would appear legitimate and would pass all Authenticode checks, and when run, would proceed to pwn the victim&rsquo;s computer.</p>
<p align="left">Microsoft announced that this trick would be blocked in a future update by changing Authenticode Verification to <a href="http://p0w3rsh3ll.wordpress.com/2014/05/24/testing-ms13-098-certificate-padding-check/">ignore the signature</a> in any file with non-null bytes after the certificates. Originally, the plan was to enable stricter verification by default in June of 2014, but after evaluating the compatibility impact, Microsoft decided not to turn on the restrictions by default; a registry key must be <a href="https://bayden.com/dl/StrictAuthenticode.reg">set</a> to enable enforcement (Change your mind? <a href="https://bayden.com/dl/NonStrictAuthenticode.reg">Undo</a>).</p>
<h4>Unvalidated Attributes</h4>
<p>You can imagine my surprise when Dropbox <a href="https://tech.dropbox.com/2014/08/tech-behind-dropboxs-new-user-experience-for-mobile/">announced</a> in early August 2014 that they were sending signed personalized installers to users. Even with the <span style="font-family: Courier New;">EnableCertPaddingCheck</span> registry key set, the Dropbox client&rsquo;s signature was deemed valid. How was this possible?</p>
<p>Microsoft&rsquo;s blog post provides a hint:</p>
<blockquote>
<p><span style="font-family: Courier New;">Although this change prevents one form of this unsafe practice, it is not capable of preventing all such forms; for example, an application developer can place unverified data within the PKCS #7 blob itself which will not be taken into account when verifying the Authenticode signature.</span></p>
</blockquote>
<p>Looking back at the Authenticode specification, we see:</p>
<blockquote>
<p><span style="font-family: Courier New;"><strong>unauthenticatedAttributes</strong></span></p>
<p><span style="font-family: Courier New;">If present, this field contains an <strong>Attributes</strong> object that in turn contains a set of <strong>Attribute</strong> objects.<span style="color: #ff0000;"> In Authenticode, this set contains only one <strong>Attribute </strong>object, which contains an Authenticode timestamp</span>.</span></p>
</blockquote>
<p>The prose in red is a bit misleading&mdash;while Microsoft might have <em>expected</em> only a timestamp to be stored there, in practice, a signer can put anything they want. So they do.</p>
<p>In Windows Explorer, right-click DropboxInstaller.exe and choose <strong>Properties</strong>. Click the <strong>Digital Signatures </strong>tab and click the <strong>Details </strong>button. On the <strong>Advanced </strong>tab, scroll to the bottom. In addition to the attribute &ldquo;Counter Sign&rdquo; (which is a cryptographically-signed timestamp, as described in my <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/03/22/authenticode-code-signing-for-developers-for-file-downloads-building-smartscreen-application-reputation.aspx">original blog</a>) there&rsquo;s an attribute whose OID (1.3.6.1.4.1.42921.2.1) lacks a <a href="http://support.microsoft.com/kb/287547">friendly name</a>. That attribute contains a 1KB block of unsigned data, in the format described in Dropbox&rsquo;s post.</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2211.image_5F00_16D86841.png" alt="image" width="369" height="197" border="0" /></p>
<p>The GoToWebinarLauncher.exe uses the same trick, with a different OID (1.3.6.1.4.1.3845.3.9876.1.1.1) and a 6840 byte data block:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2630.image_5F00_3210C142.png" alt="image" width="369" height="196" border="0" /></p>
<h3>Is Unverified Data Safe?</h3>
<p>Embedding unverified data into signed executables is absolutely a way to shoot yourself in the foot, but it is <em>possible </em>to do it securely. If you plan to go this route&nbsp; you must threat model and penetration test your approach to ensure that none of your code relying on such data trusts it. By sneaking around behind Authenticode, Windows is no longer validating the authenticity of that data&mdash;you must do so yourself.</p>
<h4>Best Practices</h4>
<p>The following are some best practices to consider:</p>
<ul>
<li>Don&rsquo;t do this at all. Getting it right is very hard, and Windows may decide to break you in the future.</li>
<li>Embed a signature within the data block yourself. If it doesn&rsquo;t validate when your code examines it, reject the data.</li>
<li>Do not embed private data in the block; the user may share the installer or fail to protect it because they don&rsquo;t realize it contains their private data.</li>
<li>If the data contains URLs to other code, validate that code&rsquo;s signature when it is downloaded.</li>
</ul>
<p>&nbsp;</p>
<h1>MD5</h1>
<p>Last year, I sent an email to the Copilot team noting that they were still using the MD5 hash algorithm when signing their code. I pointed out that changing to use the more secure SHA algorithm would probably be a trivial matter of adding a command line argument to their existing signing command (e.g. <span style="color: #9b00d3; font-family: Courier New;">-a sha1</span>).</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3731.MD5_5F00_6644EA88.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="MD5" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4572.MD5_5F00_thumb_5F00_2AF4157B.png" alt="MD5" width="461" height="304" border="0" /></a></p>
<p>Unfortunately, they haven&rsquo;t made this change yet <span style="background-color: #ffffff;">[<span style="color: #ff0000;"><strong>Update: </strong>They moved to SHA1 on 9/4/2014</span>];</span> while they haven&rsquo;t told me why, my guess is that it&rsquo;s related to the architecture they invented to dynamically sign the installers that they generate.</p>
<p>Why does this matter? Because MD5 is scary broken and should not be used.</p>
<p>A digital signature is only as strong as the hash algorithm to which the signature was applied. If a hash algorithm is broken, signed hashes could be repurposed by bad guys.</p>
<p>When it comes to hashing, there are two types of attacks:</p>
<ul>
<li><a title="Collision attack" href="http://en.wikipedia.org/wiki/Collision_attack">Collision Attack</a></li>
<li><a href="http://en.wikipedia.org/wiki/Preimage_attack">Preimage Attack</a></li>
</ul>
<p>In a collision attack, an attacker can carefully craft two different programs (one good, and one evil) that hash to the same value. In Authenticode, this would only be interesting if he could convince someone else to sign the &ldquo;good&rdquo; program; that signature he could then apply to the &ldquo;evil&rdquo; variant. This attack is <a href="http://blog.didierstevens.com/2009/01/17/playing-with-authenticode-and-md5-collisions/">possible against MD5</a> today.</p>
<p>In a second-preimage attack, an attacker takes anyone else&rsquo;s insecurely-signed <em>legitimate</em> program as input and he generates a new <em>evil</em> program that hashes to the same value as the legitimate file. He can then copy the signature to his file and it will appear that the evil file was signed by the good guy. As far as we know, there aren&rsquo;t cheap MD5 preimage attacks yet, but there will be.</p>
<p><strong>Best Practice: Don&rsquo;t use MD5</strong>.</p>
<p>While much stronger than MD5, SHA1, the default used by most certificates and tools, is starting to show weakness as well. Over the next few years, it's expected that most certificates and signatures will move to using SHA256 or SHA512 as the hash algorithm. To use SHA256 with <span style="font-family: 'courier new', courier;">signtool.exe</span>, specify the&nbsp;<span style="font-family: 'courier new', courier;">/fd SHA256</span> command line argument. Note that SHA256 Authenticode signatures cannot be created using the older <span style="font-family: 'courier new', courier;">signcode.exe</span> tool, and <a href="http://blogs.technet.com/b/pki/archive/2011/02/08/common-questions-about-sha2-and-windows.aspx">cannot be verified on Windows XP</a>, even when Service Pack 3 (which supports the use of SHA256 certificates) is installed.</p>
<p>-Eric Lawrence <br />MVP</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10555164" width="1" height="1">SecurityBest-PracticesAuthenticodeOptimizing Spriteshttp://blogs.msdn.com/b/ieinternals/archive/2014/08/21/best-practices-for-optimizing-css-sprite-images-memory-consumption.aspxThu, 21 Aug 2014 17:09:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10551876EricLaw [ex-MSFT]4http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10551876http://blogs.msdn.com/b/ieinternals/archive/2014/08/21/best-practices-for-optimizing-css-sprite-images-memory-consumption.aspx#comments<p><em>Today, I&rsquo;m writing about a topic I personally know little about, but I&rsquo;ve heard experts mention it in passing for years. I couldn&rsquo;t find any good references, hence the post below.</em></p>
<p>The first rule for building high performance web sites is to <a href="https://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-1-fewer-http-requests-7163.html">make fewer requests</a>, and using <a href="http://alistapart.com/article/sprites">CSS sprites</a> is one key and commonly-deployed means of doing so. Unfortunately, however, some websites are trading one performance problem (too many requests) for another problem (increased memory load on the client).</p>
<p>The first problem is that some designers treat &ldquo;empty space&rdquo; inside sprite images as &ldquo;free,&rdquo; because empty areas compress so well that the file size doesn&rsquo;t grow. As a consequence, they may generate images that are 50% empty or worse. The problem is that the client ultimately still needs to allocate memory for those regions when the image is decompressed for rendering. So, <strong>don&rsquo;t leave large gaps </strong>in your sprite collections. You <em>should </em><strong>leave a little padding</strong> between the sprites in the image, however, because if the sprites aren&rsquo;t padded at all, and the user has zoomed the website, a GPU may sample adjacent pixels when rendering the scaled sprite.</p>
<p>Surprisingly, the <em>shape</em> of your sprite image matters as well. Consider Facebook&rsquo;s primary sprite image. It&rsquo;s 26 pixels wide and 8227 pixels tall, and uses 32bit color. To optimize performance and memory consumption on the client, <strong>sprite collection images should be square(ish) and their dimensions should be a </strong><a href="http://stackroulette.com/gamedev/26187/undefined"><strong>power of 2</strong></a>; this image would consume less memory on the system and GPU if it were instead 512x512 pixels.</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3441.image_5F00_61138189.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3465.image_5F00_thumb_5F00_2319F0CB.png" alt="image" width="422" height="231" border="0" /></a></p>
<p>Note that further network optimization is available: If I use RIOT Optimizer to convert Facebook&rsquo;s image to use an optimal 256 color palette, the image shrinks from 143kb to 60kb; I couldn&rsquo;t see any visual differences.</p>
<p>You can easily find un-optimized sprite images with <a href="http://fiddler2.com/">Fiddler</a>. To add an <strong>Image Dimensions </strong>column to Fiddler&rsquo;s UI, right-click the column headers, choose <strong>Customize Columns</strong>, and add the column like so:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="ImageDimensions Column" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2620.image_5F00_509B108E.png" alt="Fiddler's AddColumn UI" width="392" height="191" border="0" /></p>
<p>-Eric Lawrence</p>
<p>Bonus Tip: When using JPEG (for images on your site), you should use <a href="http://calendar.perfplanet.com/2012/progressive-jpegs-a-new-best-practice/"><strong>Progressive </strong>format</a><strong>&nbsp;</strong>and <strong>4:2:0 or 4:2:2 chroma subsampling </strong>to improve size and <a href="http://blogs.msdn.com/b/ie/archive/2013/09/12/using-hardware-to-decode-and-load-jpg-images-up-to-45-faster-in-internet-explorer-11.aspx">optimize memory usage</a>. Fiddler&rsquo;s ImageView inspector will tell you what chroma subsampling was used and whether or not a JPEG is Progressive.</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10551876" width="1" height="1">Best-PracticesperformanceStrict Transport Securityhttp://blogs.msdn.com/b/ieinternals/archive/2014/08/18/hsts-strict-transport-security-attacks-mitigations-deployment-https.aspxMon, 18 Aug 2014 15:36:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10550824EricLaw [ex-MSFT]1http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10550824http://blogs.msdn.com/b/ieinternals/archive/2014/08/18/hsts-strict-transport-security-attacks-mitigations-deployment-https.aspx#comments<p>Ivan Ristic&rsquo;s meticulously researched <a href="https://www.feistyduck.com/books/bulletproof-ssl-and-tls/">Bulletproof SSL &amp; TLS</a> book spurred me to spend some time thinking about the HTTP Strict Transport Security (HSTS) feature&nbsp;<a href="http://status.modern.ie/?term=hsts">under development by the Internet Explorer team</a> and already <a href="http://caniuse.com/stricttransportsecurity">available in other major browsers</a>. HSTS enables a website to opt-in to stricter client handling of HTTPS behavior. Specifically:</p>
<ol>
<li>All HTTP connections to the HSTS-enabled host must take place over HTTPS</li>
<li>Any errors in the HTTPS certificate or handshake are fatal without override</li>
</ol>
<p>HSTS was standardized in <a href="http://tools.ietf.org/html/rfc6797">RFC6797</a> back in 2012, but the original feature idea dates <a href="https://crypto.stanford.edu/forcehttps/">back to 2008</a>.</p>
<p>While conceptually relatively simple, there are a lot of interesting intricacies around HSTS that we will explore in this post.</p>
<h2>Threats Mitigated</h2>
<p>HSTS was designed to combat the threat model whereby an active network attacker is able to control the connection between a victim browser and the Internet at large. For instance, imagine you pull out your laptop at the coffee shop and innocently type <span style="font-family: Courier New;">paypal.com</span> in the address bar and hit Go. Your network request is likely to hit the network as an insecure request for <span style="font-family: Courier New;"><strong>http</strong>://paypal.com</span> and the attacker can easily intercept this and reply with a fake version of PayPal to collect your credentials.</p>
<p>Similarly, even if you were to type <span style="font-family: Courier New;"><strong>https</strong>://paypal.com</span>, the attacker could intercept the request, and, after supplying a fake certificate, pose as the secure site. Your browser will typically show a certificate error page at this point, but too many users ignore such errors and proceed anyway. Researchers have built a variety of hacking tools like <a href="http://www.thoughtcrime.org/software/sslstrip/">sslstrip</a> to automate such attacks.</p>
<p>The stricter handling imposed by HSTS helps combat both of these threats.</p>
<h2>Opting-In</h2>
<p>Typically, a site opts-in to HSTS by sending a <strong><span style="font-family: Courier New;">Strict-Transport-Security</span> </strong>response header with a <a href="http://tools.ietf.org/html/rfc6797#section-6.1.1"><strong>max-age</strong></a> value and optionally an <a href="http://tools.ietf.org/html/rfc6797#section-6.1.2"><strong>includeSubDomains</strong></a><strong> </strong>directive. The max-age value defines the number of seconds for which the rule should remain in force; longer values are preferable. For instance, PayPal&rsquo;s current rule specifies a&nbsp;<span style="font-family: Courier New;">max-age</span> of <span style="font-family: Courier New;">14400</span> seconds, which means that the protection expires every four hours. If you were to load PayPal at home before bed, your HSTS protection would have evaporated by the time you opened your laptop in Starbucks the following morning. In contrast, Twitter&rsquo;s <strong><span style="font-family: Courier New;">max-age=631138519</span></strong> rule provides an incredible 20 years of protection, and <span style="font-family: Courier New;">addons.mozilla.org</span> is protected for a reasonable one year (<strong><span style="font-family: Courier New;">max-age=31536000</span></strong>).</p>
<h2>The Bootstrap Problem</h2>
<p>HSTS (and similar specifications) suffer from what&rsquo;s called a &ldquo;bootstrap problem&rdquo;&mdash;until and unless a user visits the target site over a secure connection, the protection is not activated. To mitigate this problem, some browsers offer what&rsquo;s called a <strong>preload list</strong>, in which some HSTS rules are distributed with the browser or its updates directly. This ensures that users are protected immediately and neatly resolves this problem as well as a privacy threat discussed later. The downside of this approach is that it requires the site operator <a href="https://hstspreload.appspot.com/">collaborate with browser vendors</a> instead of simply setting a HTTP header.</p>
<p>One exciting possibility is that some of the many new Top-Level-Domains <a href="https://www.imperialviolet.org/2014/07/06/newtlds.html">may opt-in for their entire TLD tree</a>, such that every single site under that domain (e.g. <span style="font-family: Courier New;">anexample1.secure</span>, <span style="font-family: Courier New;">otherexample2.secure</span>, etc) are all automatically protected.</p>
<h2>The includeSubDomains Directive</h2>
<p>The <strong>includeSubDomains </strong>directive enables a site to declare that the rule applies to subdomains of the current domain as well; a rule on <span style="font-family: Courier New;">a.example.com</span> with includeSubDomains set will also apply to <span style="font-family: Courier New;">b.a.example.com</span> and <span style="font-family: Courier New;">c.a.example.com</span>, for instance. This directive is important because design flaws in HTTP cookies could lead to <strong>cookie injection </strong>and/or <strong>session fixation </strong>attacks (<a href="https://www.feistyduck.com/books/bulletproof-ssl-and-tls/">Bulletproof SSL &amp; TLS</a> explains at length) if includeSubDomains is not set.</p>
<p>The crux of the threat is that browsers can&rsquo;t indicate where cookies originated when they are sent back to the server, and a child domain may set a cookie on its parent. So, even if you&rsquo;re interacting with <span style="font-family: Courier New;"><strong>https</strong>://legit.example.com</span>, an active network attacker could create a fake <span style="font-family: Courier New;"><strong>http</strong>://<strong>attacker</strong>.legit.example.com</span> and use it to set a cookie that would be sent to the secure site. The secure site would not have a trivial way to detect the phony cookie.</p>
<p>By setting the <strong>includeSubDomains </strong>directive, a site can protect itself from an attacker-created insecure child, because any child domain&nbsp;would be required to present a valid certificate.</p>
<p><span style="color: #666666;"><strong>Aside: </strong>One proposal I liked for combatting the security limitations of cookies was nicknamed <strong>MagicNamedCookies</strong>&mdash;the idea was that we&rsquo;d create some new rules for cookies based on their name-prefix. For instance, any cookie named starting with <span style="font-family: Courier New;">$$SEC- </span>could only be set or received by a HTTPS site. Similarly, a <span style="font-family: 'courier new', courier;">$$SO-</span> prefixed cookie would only ever be set in a same-origin/</span><a href="http://blogs.msdn.com/b/ieinternals/archive/2013/09/17/simple-introduction-to-p3p-cookie-blocking-frame.aspx"><span style="color: #666666;">first-party context</span></a><span style="color: #666666;">. Unfortunately, to my knowledge, no browser has plans to implement these modest and backwards-compatible improvements.</span></p>
<h2><strong>The Parent Problem</strong></h2>
<p>Unfortunately, even with the <strong>includeSubDomains</strong> directive, the unavailability of an <strong>includeParent </strong>directive means that an active man-in-the-middle attacker can perform a cookie-injection attack against an otherwise HSTS-protected victim domain. Consider the following scenario: The user visits <span style="font-family: Courier New;">https://sub.example.com</span> and gets a HSTS policy with <strong>includeSubDomains</strong> set. All subsequent navigations to <span style="font-family: Courier New;">sub.example.com</span> and its subdomains will be secure.</p>
<p>The attacker causes the victim's browser to navigate to <span style="font-family: Courier New;"><strong>http</strong>://example.com</span>. Because the HSTS policy applies only to <span style="font-family: Courier New;">sub.example.com</span> and its superdomain matches, this insecure navigation is not blocked by the user agent. The attacker intercepts this insecure request and returns a response that sets a cookie on the entire domain tree using a <span style="font-family: Courier New;">Set-Cookie</span> header. All subsequent requests to <span style="font-family: Courier New;">https://sub.example.com</span> carry the injected cookie, despite the use of HSTS.</p>
<p><strong>Best Practice </strong>To mitigate this attack, HSTS-protected websites should perform a background fetch of a resource at the first-level domain. This resource should carry a HSTS header with an <span style="font-family: courier new,courier;">includeSubDomains</span> directive that will apply to the entire domain and all subdomains.</p>
<h2>Surveying for HSTS</h2>
<p>In Fiddler, you can easily add a temporary column to show the server&rsquo;s Strict-Transport-Security response header, if any. In the black QuickExec box below the Web Sessions list, type:</p>
<p><span style="color: #0000ff; font-family: Courier New;">cols add HSTS @response.Strict-Transport-Security</span></p>
<p>&hellip; and hit Enter. The HSTS column will appear and begin showing the response header&rsquo;s value.</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="HSTS Column" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3465.image_5F00_591A4AA2.png" alt="Fiddler UI screenshot" width="576" height="250" border="0" /></p>
<p>To permanently add the HSTS column to Fiddler&rsquo;s UI, right-click the column headers, choose <strong>Customize Columns</strong>, and add the column like so:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Add a HSTS Column" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7510.image_5F00_2886CCEA.png" alt="Customize Columns Screen" width="393" height="192" border="0" /></p>
<p>In Chrome, you can see more about the HSTS list by visiting <a title="chrome://net-internals/#hsts" href="chrome://net-internals/#hsts">chrome://net-internals/#hsts</a></p>
<h3>Why click-throughs are so dangerous</h3>
<p>When the IE team replaced the IE6-era &ldquo;traffic light&rdquo; HTTPS error prompt:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7026.image_5F00_24104C23.png" alt="" width="388" height="309" border="0" /></p>
<p>&hellip;with the new blocking full-page errors, we heard a lot of negative feedback, especially from technically-savvy users. For instance, many users complained that the new pages don&rsquo;t offer an easy way to see the certificate offered by the site, not recognizing that the site&rsquo;s certificate could be entirely full of lies, deceptions that even technical users are ill-qualified to recognize.</p>
<p>Some users argued that throwing a full-page block for a expired certificate was too much&mdash;surely a recently expired certificate wasn&rsquo;t <em>really</em> unsafe, right? A few of those complainers were experts with advanced understanding of cryptography, but a poor understanding of how the Certificate Ecosystem actually works. Certificates have expiration dates, in part, because the Certificate Authorities that issue them do not want the burden of maintaining <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/04/07/enabling-certificate-revocation-check-failure-warnings-in-internet-explorer.aspx">revocation information</a> for compromised certificates indefinitely-- the same reason credit cards originally included an expiration date&mdash;keeping track of and distributing the list of stolen cards is expensive. When a compromised certificate expires, the CA is no longer under any obligation to warn clients that the certificate had been revoked. The experts in question were appalled to learn that their &ldquo;expert understanding&rdquo; of the technology had actually put them at greater risk of having their data compromised.</p>
<p>Other enthusiasts argued: &ldquo;<em>Well, okay, you&rsquo;ve convinced me that a site with a bad certificate shouldn&rsquo;t be trusted. But I enjoy watching <a href="http://www.discovery.com/tv-shows/shark-week/">Shark Week</a> and I like looking at scary things. Why not just let me go through to the site but warn me if I try to enter any data in it?</em>&rdquo;</p>
<p>There are two serious problems with this. The first is <strong>cache poisoning</strong>. If an active man-in-the-middle is attacking your connection to PayPal.com and you click through the blocking page &ldquo;just to look&rdquo;, the attacker can send back malicious JavaScript and HTML files with expiration dates that are <em>years </em>in the future. The next time you visit PayPal, even on a trusted, uncompromised connection with the shiny green badge in the address bar, the bad guy&rsquo;s code is still running in your browser:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2248.image_5F00_75B6C675.png" alt="Browser pwned" width="424" height="226" border="0" /></p>
<p>The second problem is <strong>DOM hijacking</strong>. Most browsers do not store a &ldquo;Bad certificate&rdquo; flag on the <a href="http://blogs.msdn.com/b/ieinternals/archive/2014/03/13/explaining-same-origin-policy-part-0-origins.aspx">Origin</a>, which means that a browser window with a bogus version of the site (where you clicked through a certificate error) can freely use script to manipulate a browser window that loaded the site over a secure, trusted connection. Stated another way, if <em>any </em>of your connections to a site are compromised, in effect they <em>all </em>are.</p>
<h4><strong>Common Questions</strong></h4>
<p><strong>Q:</strong> So, if click-through is so dangerous, why is it allowed for most errors?</p>
<p><strong>A: </strong>Because legitimate sites often deploy HTTPS incorrectly, and if browsers blocked access to them, the user would find another browser. This isn&rsquo;t a theory, it&rsquo;s a demonstrated fact.</p>
<p><strong>Q: </strong>Prior to the introduction of HSTS, does IE ever prevent override of certificate errors?</p>
<p><strong>A: </strong>Yes. There are a <a href="http://blogs.msdn.com/b/ieinternals/archive/2013/12/12/ie-website-security-certificate-blocking-page-missing-continue-link.aspx">few cases</a> in which the user cannot override a certificate error:</p>
<ol>
<li>If the certificate is revoked</li>
<li>If the certificate is deemed <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/06/13/windows-internet-explorer-block-rsa-key-shorter-than-1024-bits.aspx">insecure</a> (e.g. contains a 512-bit RSA key)</li>
<li>If the page is in <a href="http://blogs.msdn.com/b/ie/archive/2011/03/11/internet-explorer-9-security-part-3-browse-more-securely-with-pinned-sites.aspx">a &ldquo;pinned site&rdquo; instance</a></li>
<li>If group policy is set to Prevent Ignoring Certificate Errors</li>
</ol>
<p>&nbsp;</p>
<h3>HSTS Accidental Denial of Service</h3>
<p>One risk with HSTS&rsquo; <em>no override </em>behavior is if there&rsquo;s a configuration problem on the client that turns what would be an annoyance into a work-stopping issue. For instance, I recently sent my Surface2 into Microsoft for servicing, and when I got it back, unbeknownst to me, the system clock was set back a year. I was unable to apply any Windows Updates and it wasn&rsquo;t until I tried to visit a HTTPS site that I recognized the problem with the clock.</p>
<p>Unfortunately, Internet Explorer 11&rsquo;s and Chrome 37&rsquo;s error pages only help you recognize the <strong>incorrect system date</strong> problem if you know what you&rsquo;re looking for.</p>
<p><strong>Internet Explorer 11</strong></p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4747.IE11_5F00_5A80FE25.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="IE11 isn't much help" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/5344.IE11_5F00_thumb_5F00_6E2DE7B9.png" alt="Internet Explorer 11 Certificate Error Page" width="644" height="406" border="0" /></a></p>
<p><strong>Chrome 37 Certificate Expired Page</strong></p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8446.chrome37_5F00_404325B2.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Chrome's error page doesn't help" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4263.chrome37_5F00_thumb_5F00_1D81EDF5.png" alt="Chrome 37 error page" width="582" height="484" border="0" /></a></p>
<p>Chrome <a href="http://code.google.com/p/chromium/issues/detail?id=349653">plans to address this</a> in a future update.</p>
<p>Firefox 32 does a little bit better: it at least shows the system&rsquo;s reported &ldquo;Current time&rdquo; to allow a user to potentially say: &ldquo;Wait, that&rsquo;s not right!&rdquo;</p>
<p><strong>Firefox 32</strong></p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/5102.FF32_5F00_7AC0B637.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Shows &quot;Current Time&quot;" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8360.FF32_5F00_thumb_5F00_5C75FF41.png" alt="Firefox32 Screenshot" width="644" height="469" border="0" /></a></p>
<p>I&rsquo;ve filed a bug against IE to suggest that <a href="https://connect.microsoft.com/IE/feedbackdetail/view/949233">improving this error page</a> should be a priority to help raise websites&rsquo; confidence when deploying HSTS.</p>
<p>Beyond the incorrect system date problem, another problem arises with <strong>captive portals</strong>, like those seen when you connect to WiFi at places like Starbucks&mdash;these locations intercept all traffic until you take some action like checking a &ldquo;I agree with your terms of use&rdquo; box on a page that the portal serves. Because the portal doesn&rsquo;t have a valid certificate for the sites it is intercepting, HSTS will prevent loading of the &ldquo;terms of use&rdquo; page. Fortunately, most of these problems are easily resolved by simply visiting a HTTP page, and most modern operating systems offer a &ldquo;captive portal detection&rdquo; feature that will load an insecure page automatically when joining the network.</p>
<h3>Implementation Concerns</h3>
<p>For browser implementers, there are a number of interesting challenges when implementing HSTS. For instance, there&rsquo;s a <strong>privacy </strong>concern that a local &ldquo;attacker&rdquo; could examine the browser&rsquo;s data store for HSTS rules and thus determine whether the browser had ever visited a given site that uses HSTS but was not in the &ldquo;pre-load&rdquo; list. Similarly, a remote website could (by using a carefully constructed set of "probing" subdomains) create a token/identifier/"cookie" that could be probed to identify a user. Clearing the list of sites when the browser history is cleared, and partitioning when the browser is InPrivate<strong>&nbsp;</strong>mode mitigates this privacy risk but limits the effectiveness of the HSTS feature.</p>
<p>Unfortunately, the authors of the HSTS specification <a href="http://tools.ietf.org/html/rfc6797#section-12.4">declined to require</a> safe <a href="http://blogs.msdn.com/b/ie/archive/2011/06/23/internet-explorer-9-security-part-4-protecting-consumers-from-malicious-mixed-content.aspx">handling of Mixed Content</a> (insecure resources pulled into a secure page) meaning that HSTS-implementers are free to allow Mixed Content into protected pages, or to allow users the ability to override mixed content blocking. This is a significant shortcoming in HSTS.</p>
<p>Implementers must also make a number of design decisions in their implementation; for instance, if a DOM includes an insecure reference to a site using HSTS, should that DOM reference itself be changed, or should the secure version of the URL silently be used? How should the &ldquo;virtual redirection&rdquo; be handled by Resource Timing and other specifications? Incorrect handling of these decisions could lead to <a href="http://blogs.msdn.com/b/ieinternals/archive/2009/06/17/csshistoryprobing.aspx">probing attacks</a>.</p>
<p>For Internet Explorer in particular, there's a question about the <em>scope </em>of the feature. Windows has several major HTTP stacks (WinINET, WinHTTP, and System.NET are the most common) and because IE extensions do not rely upon IE itself for networking, they could unknowingly circumvent HSTS protections unless HSTS state is shared across all of the relevant HTTP stacks.</p>
<h2>Further Reading</h2>
<p>If you&rsquo;re interested in HSTS, you&rsquo;ll also be interested in three other specifications:</p>
<ul>
<li><a href="http://tools.ietf.org/html/draft-ietf-websec-key-pinning-20">Public Key Pinning</a> &ndash; PKP allows a site to limit <em>which certificates</em> are deemed acceptable for HTTPS connections.</li>
<li><a href="http://status.modern.ie/contentsecuritypolicy?term=content">Content Security Policy</a> &ndash; CSP allows a site to limit content retrieval to specific origins.</li>
<li><a href="http://www.w3.org/TR/mixed-content/">Mixed Content Handling</a>&nbsp;- Proposal for how User-Agents should handle Mixed Content.</li>
</ul>
<p>&nbsp;</p>
<p>-Eric Lawrence <br />MVP, Internet Explorer</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10550824" width="1" height="1">SecurityBest-PracticesstandardsinteropURL Length Limitshttp://blogs.msdn.com/b/ieinternals/archive/2014/08/13/url-length-limits-in-internet-explorer.aspxWed, 13 Aug 2014 21:52:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10549873EricLaw [ex-MSFT]1http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10549873http://blogs.msdn.com/b/ieinternals/archive/2014/08/13/url-length-limits-in-internet-explorer.aspx#comments<p>Today&rsquo;s question is a simple one: &ldquo;What is the maximum URL length supported by Internet Explorer?&rdquo;</p>
<p>And the answer, as befitting an IEInternals post, is surprisingly complicated.&nbsp;</p>
<p>The simplistic answer is that WinINET.h defines <span style="font-family: Courier New;">INTERNET_MAX_URL_LENGTH<span style="font-family: Segoe UI;"> as </span>2083</span> characters, and this limit remains in force in a number of places. However, the true limit can be both longer and shorter than this.</p>
<h2>CURI Removes Limits</h2>
<p>In Internet Explorer 7, the IE team began the process of replacing legacy string-based URL handling code with <a href="http://blogs.msdn.com/b/ie/archive/2005/08/15/452006.aspx">CURI</a>, a new object that manages URLs and exposes functionality via the <a href="http://msdn.microsoft.com/en-us/library/ie/ms775038(v=vs.85).aspx">IUri</a> interface. This object internally has no formal limit on URL length, allowing URIs up to the effective size limit of COM strings (at least several hundred megabytes in a 32bit process).</p>
<p>However, CURI was not plumbed everywhere throughout Internet Explorer, the network stack, and Windows at large, and the legacy 2083 character limit remained in practical effect until IE8. If a larger URL reached CURI but later needed to flow through a legacy codepath, the URL would either be truncated or the codepath would exit with an error.</p>
<p>In IE8, CURI was used more broadly, and HTTP and HTTPS URLs could exceed the old limit, but only if the traffic was not sent through a proxy server. The code that prepared requests for a proxy was only fixed later in IE9. However, even today there are code paths that will not handle URLs that exceed the legacy limit; for instance, the WinINET cache will not store and retrieve resources that were retrieved from a URL longer than the legacy limit.</p>
<p>Beyond the local limit, the network path itself may effectively enforce a limit; some servers will reject requests whose headers are longer than 4k or 16k, for instance, and because the URL is contained in the header, requests of huge URLs may fail.</p>
<h2>Data URIs</h2>
<p>Internet Explorer 8 introduced support for <a href="http://blogs.msdn.com/b/ie/archive/2008/08/26/ie8-performance.aspx">DataURIs</a>, a method of encoding a resource directly within a URI using base64 encoding. For performance reasons, IE8 supported DataURIs up to 32kb in length and this longer limit required changes elsewhere. For example, some DOM attributes at the time were limited to 4096 characters, a factor that would have hampered use of DataURIs in the HREF attributes of IMG elements.</p>
<p>In IE9, the 32kb limit for DataURIs was removed, although for security reasons their use remains limited to certain contexts (specifically, scenarios that create a security context, like IFRAMES, are forbidden). You still should avoid using huge DataURIs in most cases, however, as performance of large DataURIs often lags other approaches.</p>
<h2>Mailto URIs</h2>
<p>Mailto is one of the most interesting protocols in the browser, as it&rsquo;s implemented as both an <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my.aspx">Asynchronous Pluggable Protocol and an Application Protocol</a>. This means that URLMon itself both implements the protocol (to make security decisions about it) <em>and </em>delegates its handling out to the system (to invoke a mail client).</p>
<p>Why does URLMon have an Asynchronous Pluggable Protocol implementation of mailto, instead of just treating it like any other Application Protocol? Because in the 1990s, it wasn&rsquo;t uncommon to have <span style="font-family: Courier New;">&lt;FORM ACTION="mailto:joe@example.com"&gt;</span>. When the web form was submitted, the browser would serialize the data into the body of an email message and submit the form data to the specified email address using the visitor&rsquo;s email client. This process goes down Internet Explorer&rsquo;s navigation codepath and uses the URLMon APP workflow.</p>
<p>This use of the mailto syntax is now very uncommon, although it is still supported in Internet Explorer, Firefox, and Chrome. Because it necessarily reveals the sender&rsquo;s email address, IE will show the following warning:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Mailto Security Prompt" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1104.image_5F00_36C5ECFD.png" alt="Mailto Security Prompt" width="480" height="219" border="0" /></p>
<p>This arcana is relevant in this post only for one reason: Asynchronous Pluggable Protocols implement the <a href="http://msdn.microsoft.com/en-us/library/ie/aa767874(v=vs.85).aspx">IInternetProtocolInfo</a> interface to allow the browser to query the protocol for information about URLs that utilize this protocol. The browser calls the <a href="http://msdn.microsoft.com/en-us/library/ie/aa767875(v=vs.85).aspx">ParseUrl</a> to ask for a &ldquo;security URL&rdquo; that is equivalent to the target URL, and the simplistic mailto protocol implementation simply copies the entire mailto URL to the target buffer. This causes a failure because the <a href="http://msdn.microsoft.com/en-us/library/ie/ms537122(v=vs.85).aspx">GetSecurityId</a> method does not accept Security IDs longer than <span style="font-family: Courier New;">MAX_SIZE_SECURITY_ID</span>, 512 bytes, and as a consequence the attempt to launch longer mailto URLs will fail. Unfortunately, this failure doesn&rsquo;t result in a meaningful error message; the browser isn&rsquo;t robust against failures at this point and thus navigating to such URLs may result in an endlessly-spinning donut, a blank tab, or a &ldquo;Page cannot be displayed&rdquo; error.</p>
<p>There are some codepaths that manage to avoid the GetSecurityId problem, but not reliably (e.g. depending on the user&rsquo;s IE version and Zone configuration) and thus it is recommended that you avoid mailto URLs longer than 512 bytes.</p>
<h2>JavaScript URIs</h2>
<p>The JavaScript protocol is used for <a href="http://en.wikipedia.org/wiki/Bookmarklets">bookmarklets</a> (aka favlets), a lightweight form of extensibility that permits a user to click a button and run some stored JavaScript on the currently loaded page. <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/02/11/ie9-release-candidate-minor-changes-list.aspx">In IE9</a>, the team did some work to relax the length limit (from ~260 characters, if I recall correctly) to something significantly larger (~5kb, if I recall correctly).</p>
<p>However, within the browser itself, the legacy 2083 character limit remains in force when using JavaScript URIs as the source of frames or IFRAMEs (<a href="http://webdbg.com/test/js/frameset.htm">demo</a>). While I&rsquo;m not convinced that relaxing the limit is warranted (such URIs are of limited usefulness) I have <a href="https://connect.microsoft.com/IE/feedback/details/931391/internet-explorer-should-warn-on-over-long-urls">filed a bug</a> suggesting that the IE Developer tools should warn if overlong script URLs are encountered.</p>
<h2>Application Protocols</h2>
<p align="left"><a href="http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my.aspx">Application Protocols</a> are subject to even weirder limits. On Windows 8.1, for instance, if you directly pass a <a href="https://bayden.com/test/protocol/">4k Application Protocol URL</a> to ShellExecute in native code, the URL is silently truncated at the 2083 character mark.</p>
<p align="left">In Internet Explorer 11, attempting to launch an Application Protocol&nbsp;URL longer than 507 characters fails with an exception:</p>
<blockquote>
<p align="left"><img style="display: inline; background-image: none;" title="" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8816.image_5F00_638F89E8.png" alt="Error message &quot;data area was too small&quot;" width="435" height="46" border="0" /></p>
</blockquote>
<p align="left">In Chrome, if you attempt to an Application Protocol URL over 2046 characters, you&rsquo;ll see the&nbsp;regular&nbsp;Security Prompt, but clicking its&nbsp;&ldquo;Launch Application&rdquo; button does nothing.</p>
<h2>UI Limits</h2>
<p>Beyond the underlying limitations, the User Interface also enforces various limits around URL length. For instance, the browser address bar is capped at 2047 characters. Start &gt; Run is limited to 259 characters (the MAX_PATH limit of 260, which leaves one character for the null-terminator). Internet Explorer versions up to version 11 do not allow you to <a href="https://connect.microsoft.com/IE/feedbackdetail/view/837865/issue-with-add-to-favorites-in-ie10-and-ie11">bookmark URLs longer than 260 characters</a>. The Windows RichEdit v2 control's Automatic Hyperlink behavior (<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787991(v=vs.85).aspx">EM_AUTOURLDETECT</a>) truncates the link after <a href="http://stackoverflow.com/questions/27209879/increase-max-url-length-in-fiddler">around 512 characters</a>; this limit is higher in RichEdit5W controls.</p>
<p>-Eric</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10549873" width="1" height="1">limitationsnetworkinginteropBolstering Protected Modehttp://blogs.msdn.com/b/ieinternals/archive/2014/08/05/bolstering-protected-mode-against-escapes.aspxTue, 05 Aug 2014 16:27:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10547639EricLaw [ex-MSFT]0http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10547639http://blogs.msdn.com/b/ieinternals/archive/2014/08/05/bolstering-protected-mode-against-escapes.aspx#comments<p>Internet Explorer 7 introduced Protected Mode, a defense-in-depth security feature which relied upon the Windows Vista Integrity Levels (IL) system to mitigate drive-by attacks against the browser. Internet Explorer 10 introduced a stronger version of that feature, called <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx">Enhanced Protected Mode</a> (EPM), which goes beyond the legacy IL system and provides isolation using the Windows 8+ AppContainers feature.</p>
<p>Both of these features are useful in mitigating a class of exploits, but due to compatibility concerns, neither is configured as securely as possible.</p>
<p>Recently, there&rsquo;s been some excitement over the <em>rediscovery</em> of a simple escape of Protected Mode, <a href="http://www.verizonenterprise.com/resources/whitepapers/wp_escapingmicrosoftprotectedmodeinternetexplorer_en_xg.pdf">first documented back in 2010</a>. This escape is beautiful in its simplicity-- the attacker merely:</p>
<ol>
<li>Leverages some vulnerability to get remote code execution (RCE) within the LowIL process</li>
<li>Uses the RCE to run a simple webserver inside IE</li>
<li>Navigates a new IE tab to the URL of that simple server at http://localhost/</li>
<li>Serves a web page that exploits that vulnerability again</li>
</ol>
<p>Because the exploit code is re-served from http://localhost/, it may run with Intranet Zone permissions <em>outside</em> of Protected Mode, since &ldquo;localhost&rdquo; is a dotless hostname that is typically <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/06/05/the-local-intranet-security-zone.aspx">mapped to the Intranet zone</a>.</p>
<p>Now, there are some caveats that limit the availability of this escape.</p>
<p>IE7 and later <a href="http://blogs.msdn.com/b/ie/archive/2005/12/07/501075.aspx">disable the Intranet Zone by default</a> for users who are not domain-joined or on &ldquo;managed&rdquo; networks. If the Intranet Zone is disabled, http://localhost/ will load in the Internet Zone, in Protected Mode, and the escape attempt is foiled:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block;" src="https://pbs.twimg.com/media/BuJEt68CYAA4OpO.png:large" alt="" width="640" height="292" /></p>
<p>If IE10+&rsquo;s Enhanced Protected Mode feature is enabled, the escape is blocked because EPM processes are unable to listen or connect to loopback addresses, <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx">lacking</a> the internetClientServer and privateNetworkClientServer permissions. EPM is enabled in the Windows 8+ &ldquo;Metro&rdquo; / &ldquo;Immersive Browser&rdquo; by default, and can be manually enabled for Desktop IE.</p>
<p>To help ensure that you are not vulnerable to escapes of Protected Mode, you can undertake one or more of the following:</p>
<ol>
<li>Enable Protected Mode for the Intranet Zone -- Click Tools &gt; Internet Options &gt; Security &gt; Local Intranet. Tick the &ldquo;Enable Protected Mode&rdquo; box.</li>
<li>Explicitly disable the Intranet Zone &ndash; Click Tools &gt; Internet Options &gt; Security &gt; Local Intranet &gt; Sites. Untick all of the boxes.</li>
<li>Enable Enhanced Protected Mode &ndash; Click Tools &gt; Internet Options &gt; Advanced &gt; Enable Enhanced Protected Mode.</li>
</ol>
<p>* As another defense-in-depth, you might consider enabling the Zone Elevation warning, such that most attempts to navigate from the Internet Zone to the more-trusted Intranet Zone show a warning. Click Tools &gt; Internet Options &gt; Security &gt; Local Intranet &gt; Custom Level. Set &ldquo;Websites in less privileged web content zone can navigate into this Zone&rdquo; to Prompt. This will result in the following prompt when such a navigation occurs via typical means:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="Elevate" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1018.Elevate_5F00_18EBCF61.png" alt="Elevate" width="397" height="222" border="0" /></p>
<p>Unfortunately, this mitigation isn&rsquo;t useful against the sandbox escape because an attacker who has achieved full RCE inside the Protected Mode process can simply call the <a href="http://msdn.microsoft.com/en-us/library/ie/aa767962(v=vs.85).aspx">IELaunchURL</a> API; that API is not protected with this prompt.</p>
<p>While bolstering EPM/PM is great for defense-in-depth, the best way to remain secure is to ensure that the bad guys cannot exploit a vulnerability that allows remote code execution to start with. To that end, you should:</p>
<ol>
<li>Upgrade to the latest Internet Explorer version</li>
<li>Ensure that it&rsquo;s kept up-to-date via WindowsUpdate</li>
<li>Consider installing <a href="http://www.microsoft.com/en-us/download/details.aspx?id=43714">Enhanced Mitigation Experience Toolkit (EMET</a>)</li>
</ol>
<p>EMET includes cutting-edge defenses against 0-day attacks; once proven in the prototyping stage, these defenses are often then built-in to the next versions of Internet Explorer and Windows.</p>
<p>-Eric Lawrence</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10547639" width="1" height="1">SecurityZonesBetterInIE10BetterInIE11RFCs for HTTP/1.1 Updatedhttp://blogs.msdn.com/b/ieinternals/archive/2014/06/13/httpbis-completes-their-work-on-http-1.1-revisions.aspxFri, 13 Jun 2014 17:59:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10534147EricLaw [ex-MSFT]0http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10534147http://blogs.msdn.com/b/ieinternals/archive/2014/06/13/httpbis-completes-their-work-on-http-1.1-revisions.aspx#comments<p>After years of effort, the HTTPBIS working group of the IETF has completed revisions of the venerable <a href="http://tools.ietf.org/html/rfc2616">RFC2616</a> that defines the HTTP/1.1 protocol. These revisions clarify ambiguous sections of the original, deprecate problematic features, and reflect real-world implementation experiences. There&rsquo;s a quick summary of the updates <a href="http://evertpot.com/http-11-updated/">here</a>.</p>
<p>The specification has been broken up into six main specifications, and a number of ancillary specifications:</p>
<ul>
<li><a href="http://tools.ietf.org/html/rfc7230">RFC 7230: Message Syntax and Routing</a></li>
<li><a href="http://tools.ietf.org/html/rfc7231">RFC 7231: Semantics and Content</a></li>
<li><a href="http://tools.ietf.org/html/rfc7232">RFC 7232: Conditional Requests</a></li>
<li><a href="http://tools.ietf.org/html/rfc7233">RFC 7233: Range Request</a></li>
<li><a href="http://tools.ietf.org/html/rfc7234">RFC 7234: Caching</a></li>
<li><a href="http://tools.ietf.org/html/rfc7235">RFC 7235: Authentication</a></li>
<li><a href="http://tools.ietf.org/html/rfc7236">RFC 7236: Authentication Scheme Registrations</a></li>
<li><a href="http://tools.ietf.org/html/rfc7237">RFC 7237: Method Registrations</a></li>
<li><a href="http://tools.ietf.org/html/rfc7238">RFC 7238: the 308 status code</a></li>
<li><a href="http://tools.ietf.org/html/rfc7239">RFC 7239: Forwarded HTTP extension</a></li>
</ul>
<p>Meanwhile, the Internet Explorer and WinINET teams are <a href="http://status.modern.ie/http2?term=http%2F2">at work</a> on the next version (HTTP/2) of the protocol. It&rsquo;s a very exciting time to be working on browser networking.</p>
<p>Incidentally, if you&rsquo;re interested in learning the nitty-gritty of browser networking, Ilya Grigorik&rsquo;s excellent and thorough book <a href="http://chimera.labs.oreilly.com/books/1230000000545">High Performance Browser Networking</a> can be read online for free, or <a href="http://www.amazon.com/gp/product/1449344763/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1449344763&amp;linkCode=as2&amp;tag=baydensystems">purchased at Amazon</a>.</p>
<p>-Eric</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10534147" width="1" height="1">standardsnetworkingI'll be at the Velocity Conference in Santa Clarahttp://blogs.msdn.com/b/ieinternals/archive/2014/06/09/see-you-at-the-velocity-conference.aspxMon, 09 Jun 2014 19:32:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10532581EricLaw [ex-MSFT]0http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10532581http://blogs.msdn.com/b/ieinternals/archive/2014/06/09/see-you-at-the-velocity-conference.aspx#comments<p>Later this month, I'll be at the Velocity Web Performance and Operations conference in Santa Clara. I hope to see some of you there!</p>
<p><a href="http://velocityconf.com/velocity2014?cmp=ba-velocity-confreg-home-vlsc14_im_attending"> <img src="http://cdn.oreillystatic.com/en/assets/1/event/113/velocity2014_attending_728x90.gif" alt="Velocity Conference 2014" width="728" height="90" border="0" /> </a></p>
<p>Beyond my "Lightning Demo" of new Fiddler features, some IE Engineers will be <a href="http://velocityconf.com/velocity2014/public/schedule/detail/35463">presenting</a>&nbsp;the latest on performance optimization.</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10532581" width="1" height="1">fiddlerUnicode in URL changes for IE11http://blogs.msdn.com/b/ieinternals/archive/2014/04/22/internet-explorer-11-unicode-utf8-url-query-string-international.aspxTue, 22 Apr 2014 21:57:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10519565EricLaw [ex-MSFT]6http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10519565http://blogs.msdn.com/b/ieinternals/archive/2014/04/22/internet-explorer-11-unicode-utf8-url-query-string-international.aspx#comments<p>I wrote a bit about <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/07/13/internet-explorer-and-international-text-encoding-unicode-punycode-ansi-oh-my.aspx">Internet Explorer&rsquo;s International Settings</a> back in July of 2012. Internet Explorer 10 and 11 quietly brought some changes:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/6355.image_5F00_775C6563.png" alt="image" width="800" height="138" border="0" /></p>
<p>In IE10, the <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/03/01/ie10-beta-consumer-preview-minor-changes-changelist.aspx">Use UTF-8 for mailto links option was removed</a>.</p>
<p>In IE11, the misleadingly-named <strong>Send UTF-8 URLs</strong> option is renamed to correctly reflect its function (<strong>Send URL path as UTF-8</strong>) and it&rsquo;s joined by two off-by-default options to <strong>Send UTF-8 query strings</strong>. We had considered adding these options in IE8 but ultimately decided that we didn&rsquo;t have time and runway to introduce a potentially-breaking change to IE&rsquo;s handling of non-ASCII query strings.</p>
<p>Unfortunately, as noted in <a href="https://connect.microsoft.com/IE/feedback/details/857431/unescaped-non-ascii-characters-in-url-query-being-completely-broken#tabs">this CONNECT bug</a>, these new checkboxes don&rsquo;t appear to work. Even when you tick both <strong>Send UTF-8 query strings</strong> boxes and restart IE, IE fails to update its behavior.</p>
<p>Consider the following URL:</p>
<blockquote>
<p><span style="color: #9b00d3; font-size: x-small;">http://webdbg.com/ほむら/?Query=ほむら</span></p>
</blockquote>
<p>On a US-English system, if you paste this URL into IE11&rsquo;s address bar and hit enter, you can watch in Microsoft Network Monitor and see that the query string has been thunked down to ASCII with the three Unicode characters replaced by three question marks:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3730.image_5F00_271A0DE3.png" alt="image" width="657" height="81" border="0" /></p>
<p>This problem only applies to the query string; Unicode characters in the path are still sent as %-encoded UTF-8.</p>
<p>In contrast, navigating via Chrome&rsquo;s Address bar shows expected results:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3666.image_5F00_74B63A63.png" alt="image" width="653" height="97" border="0" /></p>
<p>-Eric Lawrence</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10519565" width="1" height="1">bugsinteropinternationalInternet Explorer 11 and Perfect-Forward-Secrecyhttp://blogs.msdn.com/b/ieinternals/archive/2014/04/11/windows-8.1-update-1-adds-new-tls-cipher-suites-and-enhances-perfect-forward-secrecy-support.aspxFri, 11 Apr 2014 17:04:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10516549EricLaw [ex-MSFT]4http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10516549http://blogs.msdn.com/b/ieinternals/archive/2014/04/11/windows-8.1-update-1-adds-new-tls-cipher-suites-and-enhances-perfect-forward-secrecy-support.aspx#comments<p>In case you missed it, the recent Windows 8.1 Update update adds four new ciphersuites (including two supported by Chrome32) and changes the ciphersuite order to prefer algorithms that offer Perfect-Forward-Secrecy. You can read more about <a href="http://support.microsoft.com/kb/2929781/en-us">this update here.</a></p>
<p>Wikipedia has a <a href="http://en.wikipedia.org/wiki/Perfect_forward_secrecy">nice article on PFS</a>, but the short summary is as follows:</p>
<p>When your browser makes a HTTPS connection, typically, two keys are used: the client generates a random secret key that is used by a fast, symmetric (&ldquo;bulk&rdquo;) encryption algorithm, and it encrypts that secret using the public asymmetric key (slow) provided by the server. The problem is that if the server&rsquo;s private key is ever <a href="http://xkcd.com/1354/">compromised</a>, an attacker who had previously recorded your traffic could then decrypt the secret symmetric key and turn the &ldquo;gibberish&rdquo; he had recorded back into the plaintext of your web session&rsquo;s traffic, even if it took place months or years ago.</p>
<p>In PFS, each connection to the server generates a new asymmetric <a href="https://www.imperialviolet.org/2011/11/22/forwardsecret.html">key pair specific to that session</a>, such that if the server&rsquo;s private key is compromised, only <em>future </em>traffic is at risk of disclosure.</p>
<p>The Windows 8.1 Update isn&rsquo;t the first time that IE has supported PFS, but the new ciphersuites added in this update have performance characteristics that make servers more likely to use them.</p>
<p>-Eric</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10516549" width="1" height="1">SecurityhttpsBetterInIE11Managed Code Browser Extensionshttp://blogs.msdn.com/b/ieinternals/archive/2014/04/10/do-not-write-browser-extensions-toolbars-bhos-and-activex-in-managed-dotnet-code.aspxThu, 10 Apr 2014 15:54:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10516150EricLaw [ex-MSFT]7http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10516150http://blogs.msdn.com/b/ieinternals/archive/2014/04/10/do-not-write-browser-extensions-toolbars-bhos-and-activex-in-managed-dotnet-code.aspx#comments<p>I <em>love </em>the .NET Framework. I&rsquo;ve been programming in C# since 2001, I spent much of my free time for a decade building <a href="http://fiddler2.com/">Fiddler</a> on .NET, and I now code in C# for a living. .NET provides a fantastic, highly-productive platform suitable for building a huge range of tools and applications, and as it grows in power and performance, its scope has only grown.</p>
<p>However, there&rsquo;s one task for which .NET code isn&rsquo;t suitable: building in-process browser extensions like Toolbars, BHOs, Pluggable Protocols, and ActiveX controls. These COM-based extensibility mechanisms were exposed long before the .NET Framework, and while .NET offers powerful interop with COM, it&rsquo;s not an appropriate technology to implement browser extensions.</p>
<p>.NET-based browser extensions are responsible for significant <a href="http://blogs.msdn.com/b/ieinternals/archive/2009/08/21/agcore-addon-hangs-internet-explorer.aspx">performance and reliability</a> problems in the browser. Even now that the .NET Framework version 4 resolved the side-by-side versioning problem, Raymond Chen notes that in-process browser &amp; shell extensions <a href="http://blogs.msdn.com/b/oldnewthing/archive/2013/02/22/10396079.aspx">shouldn&rsquo;t be written in managed code</a>. The <strong>Issues Specific to the .NET Framework </strong>section of the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd758089(v=vs.85).aspx">Guidance for Implementing In-Process Extensions</a> MSDN article explains this topic in further detail.</p>
<p>Of the extension types, Toolbars and BHOs are the most problematic, as they are automatically loaded by every tab upon startup and often perform processing on every page load. The performance impact of such extensions can severely hurt the overall performance of the browser. Managed Pluggable Protocols and ActiveX controls are somewhat less problematic, as they&rsquo;re only loaded when invoked by web content, but such usage should still be avoided.</p>
<p>Obviously, .NET remains a great choice for out-of-process interaction with browsers (e.g. like Fiddler or applications invoked by <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my.aspx">Application Protocol url schemes</a>). If necessary, you could even use .NET to do most of the heavy lifting for your BHO or toolbar&mdash;just do so by writing a native-code COM extension (using C++, Delphi, etc) that itself uses RPC/named pipes/etc to marshal data to the out-of-process .NET code. That way, the only code running in-process with the browser is native and you avoid loading the framework into the browser process.</p>
<p>Over the years, IE has increased the restrictions and hurdles placed on binary browser extensions, going so far as to block them entirely in the Immersive/Metro mode of the browser. If there&rsquo;s a new extension model in a future version of IE, I expect it will be based on JavaScript. But who knows, perhaps one day we&rsquo;ll see a safe, fast, and stable way to build add-ons in managed code that is automatically executed out-of-process.</p>
<p>-Eric Lawrence</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10516150" width="1" height="1">Best-Practicesperformancedevadd-onsaddonsAwesome IE11 News, in case you missed ithttp://blogs.msdn.com/b/ieinternals/archive/2014/04/03/awesome-internet-explorer-11-announcements-at-build-2014.aspxThu, 03 Apr 2014 14:19:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10513634EricLaw [ex-MSFT]1http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10513634http://blogs.msdn.com/b/ieinternals/archive/2014/04/03/awesome-internet-explorer-11-announcements-at-build-2014.aspx#comments<p>Big news from the //build conference this week:</p>
<p>1. The IE team has announced a feature-implementation tracking site, which you can find at <a href="http://status.modern.ie/">http://status.modern.ie/</a>. This site shows what IE supports (and when it supported it) and provides a look at what to expect in <em>future </em>versions of Internet Explorer. It also provides links to relevant specifications and information about cross-browser support. This is an awesome resource and I&rsquo;m very excited that it&rsquo;s out! Tweet any feedback to <a href="https://twitter.com/IEDevChat">@iedevchat</a>.</p>
<p>2. IE11 now offers an <a href="http://blogs.msdn.com/b/ie/archive/2014/04/02/stay-up-to-date-with-enterprise-mode-for-internet-explorer-11.aspx">Enterprise Mode</a> feature, which allows IT administrators to deploy a list of sites which should run in IE8-Compatibility mode. This feature significantly improves compatibility with legacy sites, while offering major performance improvements over IE8 itself.</p>
<p>3. The F12 Developer tools have been enhanced, and IE11 will ship on Windows Phone 8.1. You can read all about it <a href="http://blogs.msdn.com/b/ie/archive/2014/04/02/announcing-an-updated-version-of-internet-explorer-11-available-on-windows-8-1-windows-7-and-windows-phone-8-1.aspx">on the IEBlog</a>.</p>
<p>For all the gory details, check out this&nbsp;<a href="http://msdn.microsoft.com/en-us/library/ie/dn641599(v=vs.85).aspx">MSDN article&nbsp;on the IE11 on Windows 8.1&nbsp;Update</a>.</p>
<p>-Eric</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10513634" width="1" height="1">BetterInIE11Windows Server as a Workstationhttp://blogs.msdn.com/b/ieinternals/archive/2014/03/17/internet-explorer-windows-server-enhanced-security-configuration-esc-html5-video-playback.aspxMon, 17 Mar 2014 16:39:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10508468EricLaw [ex-MSFT]4http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10508468http://blogs.msdn.com/b/ieinternals/archive/2014/03/17/internet-explorer-windows-server-enhanced-security-configuration-esc-html5-video-playback.aspx#comments<p>Back in the Windows 2003 timeframe, Microsoft had a problem. The security press of the time liked to put out charts showing which operating systems had the most vulnerabilities. Windows 2000 wasn&rsquo;t looking so hot, owing to the fact that Windows 2000 Server had a full web browser built-in, &ldquo;out of the box.&rdquo; Even if a server administrator followed best-practices and never booted the browser, Windows still looked bad in the charts because all browsers, including IE5 and IE6, had an endless stream of security patches.</p>
<p>Windows cobbled together a small task force to address this problem by introducing the <strong>Enhanced Security Configuration </strong>feature for Internet Explorer when run on Windows Server.</p>
<h2>ESC: Enhanced Security Configuration</h2>
<p>ESC makes myriad small changes across the browser, but the primary change is that it kicks the security level of the <strong>Internet Zone </strong>up to High:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/5187.image_5F00_4F9792C0.png" alt="image" width="427" height="399" border="0" /></p>
<p>By setting the Internet Zone to use the High Template, ActiveX and script execution are blocked and a huge number of features are disabled by default. This simple change alone would have been sufficient to make the charts look dramatically better (because virtually all browser exploits require one or more of the disabled features).</p>
<p>To help the user understand that this configuration is enabled, the default homepage is changed to a very wordy explanation:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2248.image_5F00_5F3A2E82.png"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1680.image_5F00_thumb_5F00_0E8BA40D.png" alt="image" width="526" height="228" border="0" /></a></p>
<p>This could be summarized as: &ldquo;<span style="color: #ff0000;">This is a server. Don&rsquo;t browse from your server. That&rsquo;s what workstations are for!</span>&rdquo;</p>
<p>However, the notifications don&rsquo;t stop there. As you browse around, you&rsquo;ll see many <em>ancient </em>notifications that were long ago hidden by the default security level template, like this prompt from the 1990s that attempted to explain what HTTPS was all about:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1682.image_5F00_72E9A8C7.png" alt="image" width="365" height="194" border="0" /></p>
<p>Any time you visit a website that wants to run script or perform another action that is not permitted due to the changes made by ESC, a prompt is shown:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1602.image_5F00_12988290.png" alt="image" width="416" height="373" border="0" /></p>
<p>What this prompt really means is: &ldquo;<span style="color: #ff0000;">Hey, we noticed that you&rsquo;re browsing from your server. We really don&rsquo;t want you to do that, but we&rsquo;ll let you. If you&rsquo;re really really committed to browsing securely from your server, you can load the page in this mode which will probably break it. Or you can manually add this site to the list of sites you trust to run with regular permissions</span>.&rdquo;</p>
<p>Some &hellip; <em>hyper-vigilant </em>&hellip;<em>&nbsp;</em>users find these prompts useful and don&rsquo;t seem to mind them. Some administrators feel they have a genuine need to use a browser on the server itself and they don&rsquo;t feel they can accomplish their goals by browsing from a workstation.</p>
<p>However, if you&rsquo;re simply a developer who&rsquo;s running a Windows Server as a workstation (e.g. your dev box) so you have a full IIS / SQL instance, etc, and you&rsquo;re not really using it as a production server, it is likely that these prompts will quickly get intensely irritating.</p>
<p>Fortunately, you can very easily instruct the Server to knock it off. From the <strong>Local Server </strong>tab of the <strong>Server Manager</strong>, click the link next to the <strong>IE Enhanced Security Configuration </strong>item:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4762.image_5F00_38FA65DB.png" alt="image" width="524" height="274" border="0" /></p>
<p>A dialog will launch that allows you to control the ESC feature:</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7827.image_5F00_620504D7.png" alt="image" width="432" height="459" border="0" /></p>
<p>Changes take effect the next time Internet Explorer starts.</p>
<p>Note that clicking the &ldquo;More about Internet Explorer Enhanced Security Configuration&rdquo; link will launch a browser which prompts you with the ESC &ldquo;Content Blocked&rdquo; dialog for 9 different domains (including Facebook and about:blank) before rendering the <a href="http://windows.microsoft.com/en-US/internet-explorer/internet-explorer-help">generic Internet Explorer Help page</a>.</p>
<p>After you disable ESC, the browser&rsquo;s default homepage will change to a warning to remind you that you&rsquo;ve done so:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/0116.image_5F00_6AF49716.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2438.image_5F00_thumb_5F00_1393031E.png" alt="image" width="526" height="257" border="0" /></a></p>
<p>The ESC feature has received only minimal attention from the IE development team over the last decade. By default, the recommended &ldquo;Windows Server Core&rdquo; configuration doesn&rsquo;t include a GUI at all, which means that servers that are acting as proper &ldquo;servers&rdquo; are in a very secure configuration automatically. Even when you enable the GUI for Server, Windows supports uninstalling the Internet Explorer browser if it isn&rsquo;t needed.</p>
<p>In my opinion, the ESC feature should probably be yanked out&mdash;it&rsquo;s irritating, unnecessary, and has an ongoing maintenance cost for the IE development team.</p>
<p>For now, however, disabling ESC isn&rsquo;t the only change you need to make to make your server behave like a workstation.</p>
<h2>HTML5 Video</h2>
<p>If you&rsquo;re using a PC running Windows Server 2012 R2, you might find that HTML5 video doesn&rsquo;t play in Internet Explorer. For instance, when visiting a page like the <a href="http://ie.microsoft.com/testdrive/Performance/FishBowl/Default.html">FishBowl benchmark</a>, it might stop loading at the &ldquo;Initializing&rdquo; stage, with the F12 Developer Tools&rsquo; Console tab showing an inscrutable error:</p>
<blockquote>
<p><span style="color: #0000ff; font-family: Courier New;">SCRIPT65535: Unexpected call to method or property access.</span></p>
</blockquote>
<p>The problem is that, by default, Windows Server does not include the HTML5 video codecs, and thus they&rsquo;re not available to Internet Explorer. To resolve this, simply boot a Windows PowerShell command prompt (e.g. by clicking the icon in the task bar):</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/5165.image_5F00_1EBF1E19.png"><img style="margin: 0px; display: inline; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3583.image_5F00_thumb_5F00_179FE1A1.png" alt="image" width="36" height="32" border="0" /></a></p>
<p>and then enter the following two commands:</p>
<blockquote>
<p><code><span style="color: #0000ff;">Import-Module ServerManager</span></code></p>
<p><code><span style="color: #0000ff;">Install-WindowsFeature Desktop-Experience</span></code></p>
</blockquote>
<p>A reboot is required for the installation to complete.</p>
<p>&nbsp;</p>
<p>-Eric Lawrence<br />MVP - Internet Explorer</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10508468" width="1" height="1">SecurityBest-PracticesSame Origin Policy Part 0: Originshttp://blogs.msdn.com/b/ieinternals/archive/2014/03/13/explaining-same-origin-policy-part-0-origins.aspxFri, 14 Mar 2014 00:47:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10507805EricLaw [ex-MSFT]1http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10507805http://blogs.msdn.com/b/ieinternals/archive/2014/03/13/explaining-same-origin-policy-part-0-origins.aspx#comments<p>Recently, someone asked a pretty simple question: &ldquo;<em>Why doesn&rsquo;t IE consider the port when evaluating Same Origin Policy?</em>&rdquo; and I realized that my Same-Origin-Policy series lacks an in-depth look at the concepts surrounding <em>origins</em>.</p>
<p><strong>Table of Contents: Same Origin Policy Posts</strong></p>
<ul>
<li>Part 0 &ndash; (This post) What&rsquo;s an Origin</li>
<li><a href="http://blogs.msdn.com/b/ieinternals/archive/2009/08/28/explaining-same-origin-policy-part-1-deny-read.aspx">Part 1 &ndash; Deny Read</a></li>
<li><a href="http://blogs.msdn.com/b/ieinternals/archive/2012/04/03/explaining-same-origin-policy-part-2-limited-write.aspx">Part 2 &ndash; Limited Write</a></li>
<li>Part 3 &ndash; Limited Execute (to be written)</li>
</ul>
<h2>Why do we need origins at all?</h2>
<p>The Web is comprised of many different sites (&ldquo;principals&rdquo;) &ndash; some official and legitimate (e.g. your bank), some outright malicious (phishers) and every shade in between. As a consequence, browsers must keep the code and data between these principals separated, or the &ldquo;bad guys&rdquo; could use their code, running in your browser, to attack or steal data from the &ldquo;good guy&rdquo; sites your browser can access.</p>
<p>On the web, origins are meant to represent a single security principal, or as I sometimes call it, &ldquo;a single sphere of control." You don&rsquo;t want each individual page to be an isolated origin, or it would be cumbersome to build interesting websites and applications<sup>1</sup>. On the other hand, you don't want an origin to encompass resources that are under the control of unrelated entities, or those resources will be able to use the client's browser to attack one another.</p>
<p>For instance, na&iuml;ve sites in the early web used to allow different users to serve content from the same host but different path (e.g. <span style="font-family: Courier New;">//example.com/~userA</span> and <span style="font-family: Courier New;">example.com/~userB</span>), and security isolation was utterly nonexistent<sup>2</sup>, because siteA and siteB could scribble all over one another.</p>
<p>Okay, so we want to <em>partition</em> the websites controlled by different entities. Each entity is identified by its &ldquo;origin.&rdquo;</p>
<h2>Origin &asymp; URLMon SecurityId</h2>
<p>Within Internet Explorer and (to some extent) across Windows, UrlMon is responsible for managing the access permissions of web content. In most cases, URLMon will end up examining the <span style="font-family: Courier New;">SecurityId</span> of the source and target resources to determine whether access should be granted to the target. Technically, a SecurityId is an opaque byte array up to 512 bytes long (<span style="font-family: Courier New;">MAX_SIZE_SECURITY_ID</span>) but, in practice, the SecurityId typically follows the format mentioned in the <a href="http://msdn.microsoft.com/en-us/library/ie/ms537149(v=vs.85).aspx"><span style="font-family: Courier New;">GetSecurityId</span></a> method&rsquo;s documentation:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;">&nbsp;&nbsp;&nbsp; &lt;scheme&gt;:&lt;hostname&gt;+&lt;zone#&gt;</span></p>
<p>As you can see, this is <em>similar </em>to, but not exactly equivalent to the recent <a href="http://tools.ietf.org/html/rfc6454">RFC6454 definition</a>, which defines the typical origin as:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;">&nbsp;&nbsp;&nbsp; triple(uri-scheme, uri-host, uri-port)</span></p>
<p>In typical cases, URLMon will check that the source and target Security Ids match exactly, although there&rsquo;s also a <a href="http://msdn.microsoft.com/en-us/library/aa359661(v=vs.85).aspx"><span style="font-family: Courier New;">CompareSecurityIds</span></a> function which performs a more-liberal (and thus potentially-dangerous) comparison.</p>
<p>If the SecurityIds match exactly, access is typically granted; if the SecurityIds don&rsquo;t match, an override setting (e.g. <span style="font-family: Courier New;">URLACTION_CROSS_DOMAIN_DATA</span>) may be consulted before access is denied.</p>
<h2>So, why <em>isn&rsquo;t</em> the Port part of URLMon&rsquo;s SecurityId?</h2>
<p>Short answer: I don&rsquo;t know &ndash; it was before my time.</p>
<p>Longer answer: I have two guesses. Guesses can be either right or <a href="http://meta.wikimedia.org/wiki/Cunningham's_Law">useful</a>.</p>
<p>Guess #1: In the early days of the Internet, virtually all of the hosts were running some form of Unix-like operating system. Unix was a multi-user OS from the start, and by default, any user could listen on a TCP/IP port (only "low-numbered" ports &lt;1024 were restricted to admins). So, if the concept of an Web Origin didn't include a port, Unix UserA could stand up a web server and attack Unix UserB. In such a world, the port clearly needs to be a part of the Origin.</p>
<p>However, back in those early days of the web, Windows was basically a single-user operating system, which made the "different users running different servers from the same box" scenario less applicable for a Windows web server. (Of which, there really weren't many until Windows NT became popular, at which point Windows had become a true multi-user OS). The ports <em>could</em> have been considered a part of the SecurityId at that time, but changing this would break any corporate applications that had been written with the expectation that they were not. For instance, you could have a Intranet Timesheet app running on one port and a Payroll app running on another and it might be desirable to allow them to interact.</p>
<p>Guess #2: When URLMon was first built, it wasn&rsquo;t entirely clear what protocols would be relevant in the future. As a consequence, URLMon abstracted and generalized many concepts, and &ldquo;port&rdquo; is a concept which is specific to network protocols based on IP. As such, it might not have been deemed sufficiently generalized to use as a part of the SecurityId. Furthermore, a protocol implementer <em>could </em>include any non-default port in the host component of the SecurityId even though that never happened.</p>
<h4>Could SecurityIds be changed to include the port?</h4>
<p>Today, I think a decent argument could be made that IE should consider port to be a part of the origin. That's especially true now that IE supports CORS for XHR, which means that it would be possible for a site to "fix itself" by offering up an Access-Control-Allow-Origin directive for XHR interactions (although <br />DOM-interactions would be still be blocked).</p>
<p>However, there are three problems with changing this now:&nbsp;&nbsp;&nbsp;</p>
<ol>
<li><strong>Compat</strong>. Obviously, this would be a breaking change for any site that was written to ancient IE and never needed to work cross-browser.</li>
<li><strong>Completeness</strong>. In IE8 the <em>native</em> XmlHttpRequest object included port as a part of the same-origin-policy evaluation. This was our first stab at trying to move over to the standards-based SOP. Unfortunately, the outcome was awful&mdash;a number of sites refused to use the native XHR and kept using the ancient MSXML XHR object to keep their sites working. <br /> <br />So we didn't get standards OR security. We reverted the "port as part of origin for XHR" in a future update. </li>
<li><strong>The problems IE&rsquo;s behavior causes are mostly &ldquo;solved&rdquo;. </strong>Largely due to #2, sites have been forced to solve for this issue. And the solution is pretty simple-- if you want to host multiple unrelated sites on a single box, and have isolation between them, you simply use multiple hostnames, one per principal, and you only route traffic to the destination port if the hostname is correct. That way, traffic is properly isolated regardless of browser version.</li>
</ol>
<p>Even if IE12 were to change in behavior to include the port as a part of the origin, sites won&rsquo;t be able to rely upon such isolation for a very very long time; there are hundreds of millions of legacy clients out there, and an unknown number of extensions and plugins that might never be updated with the new rules.&nbsp; <br />&nbsp;&nbsp; <br />When we considered making a change in IE8 and future releases, we had to decide: "<em>Is the (unknown) compat hit we'd take today worth the (unknown) security value this would provide at some point in the future?</em>" And our decision in IE8-IE11 was "<em>no</em>."</p>
<h2>Quirks from the Zone in the SecurityId</h2>
<p>In most cases, Internet Explorer&rsquo;s inclusion of the Zone in the SecurityId is redundant, because in most scenarios the Zone of a resource is determined by its hostname, which is already a part of the SecurityId. However, there are two scenarios where two SecurityIds may have the same hostname but a different zone.</p>
<h4>Zone Changes</h4>
<p>A user&rsquo;s security zone configuration can change at almost any time; a user can simply click Tools &gt; Internet Options &gt; Security and move a site from one zone to another. This is, at best, a rare corner case.</p>
<p>Amusingly, real-life experience presented one case where having the Zone in the SecurityId is problematic. Many users inside Microsoft use Outlook Web Access (OWA) to access their mail at <span style="font-family: Courier New;">https://mail.microsoft.com/</span>. OWA is a great example of a &ldquo;single-page web application&rdquo; where the user keeps a single web page loaded for hours; it uses XHR and IFRAMEs to pull data from the server as needed. One day, we started getting reports that users were having problem with their mail when they brought their laptops from work to home and vice versa. Looking at the JavaScript exception logs, there were a flood of Access Denied errors.</p>
<p>What went wrong?</p>
<p>The IT department had recently updated the <a href="http://blogs.msdn.com/b/ieinternals/archive/2013/10/11/web-proxy-configuration-and-ie11-changes.aspx">Proxy AutoConfiguration Script</a> so that accessing the mail server would go <span style="font-family: Courier New;">DIRECT</span>, bypassing the proxy. Doing so causes the site to be <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/06/05/the-local-intranet-security-zone.aspx">treated as Intranet Zone</a>.&nbsp; As a consequence, when users moved from work to home or vice versa, the PAC script was either disabled or enabled and the SecurityIds generated for the mail servers resources bounced between Internet and Intranet. The mismatched zone number caused the Same-Origin-Policy checks to fail.</p>
<p>To resolve the issue, we suggested that the IT Department should use Group Policy to force the mail site into the Intranet zone, so that its SecurityId would remain stable regardless of whether or not the proxy script were in use.</p>
<h4>SECURITY=RESTRICTED IFrames</h4>
<p>Long before the advent of the HTML5 Sandbox attribute, IE6 added the ability for a page to <a href="http://blogs.msdn.com/b/ie/archive/2008/01/18/using-frames-more-securely.aspx">restrict a subframe&rsquo;s content</a>, by setting an <span style="font-family: Courier New;">SECURITY=RESTRICTED</span> attribute on the IFRAME. This attribute causes the content of the frame to be treated as if it were running in the Restricted Sites zone, regardless of what hostname it is served from. Interestingly, SOP suggest we shouldn&rsquo;t be able to use an Internet Zone page to writing into a Restricted Zone page from the same host, but this restriction <a href="http://www.webdbg.com/test/frames/restrict.asp">doesn&rsquo;t seem to be enforced</a>.</p>
<h2>Quirks for File URIs</h2>
<p>Typically, the SecurityId consists of a protocol scheme, hostname, and zone number. Hostnames are canonicalized to lowercase and thus most SecurityIds are <em>effectively case-insensitive</em>.</p>
<p>However, file URIs&rsquo; SecurityIds consist of:</p>
<p><span style="color: #0000ff; font-family: Courier New;">&nbsp;&nbsp;&nbsp; &lt;scheme&gt;:&lt;hostname&gt;/&lt;<span style="color: #ff0000;">firstPathComponent</span>&gt;+&lt;zone&gt;</span></p>
<p>The first path component is included as part of the SecurityId because file shares are <em>named</em>, and different shares may have different access lists. For instance <span style="font-family: Courier New;">file://server/Accounting</span> and <span style="font-family: Courier New;">file://server/Dev/</span> are considered different origins.</p>
<p>On some file systems, paths and share names are case-sensitive, so as a consequence, the SecurityId of a file URI is also case-sensitive. You will find that <span style="font-family: Courier New;">file://server/Dev/Page1.htm </span>can interact with <span style="font-family: Courier New;">file://server/Dev/Page2.htm</span> but not <span style="font-family: Courier New;">file://server/<strong>d</strong>ev/Page3.htm</span> because the Origin for the first two pages is <span style="font-family: Courier New;">FILE:server/Dev</span> while the origin for the third is <span style="font-family: Courier New;">FILE:server/dev</span>.</p>
<h3>Random arcana</h3>
<p>In a future update, we&rsquo;ll look at the relationship between origin and:</p>
<ul>
<li>postMessage</li>
<li>cookies (secure &amp; insecure)</li>
<li>XHR&rsquo;s Origin header</li>
<li>relaxation of document.domain</li>
</ul>
<p>-Eric Lawrence</p>
<p><sup>1 </sup>Trying to retrofit &ldquo;fine-grained origins&rdquo; onto the Web is a risky proposition, as Jackson and Barth explained in <a href="http://seclab.stanford.edu/websec/origins/fgo.pdf&lrm;">their great paper</a>.</p>
<p><sup>2</sup> This is commonly called "The GeoCities problem" but I think it was some other site (maybe AngelFire?) that did this.</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10507805" width="1" height="1">SecurityZonesinteropBrowser Arcana: IP Literals in URLshttp://blogs.msdn.com/b/ieinternals/archive/2014/03/06/browser-arcana-ipv4-ipv6-literal-urls-dotted-va-dotless.aspxThu, 06 Mar 2014 19:37:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10505853EricLaw [ex-MSFT]3http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10505853http://blogs.msdn.com/b/ieinternals/archive/2014/03/06/browser-arcana-ipv4-ipv6-literal-urls-dotted-va-dotless.aspx#comments<p>While virtually all web traffic flows over connections based on the Internet Protocol, most of the time your browser first <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/09/26/dns-lookups-caching-failover-in-internet-explorer-and-wininet.aspx">uses DNS to look up </a>the target hostname&rsquo;s IP address. However, sometimes URLs directly specify an IP address, skipping DNS altogether. When an IP appears directly within such an URL, it is said to have an <strong>IP-Literal Hostname</strong>. In general, using IP-Literal hostnames is a bad idea (as they don&rsquo;t support DNS Failover and other useful features) but in rare cases their use may be reasonable-- e.g. when communicating directly with network devices like switches and routers.</p>
<p>The most common IP-Literal URLs use the <a href="http://en.wikipedia.org/wiki/Dot-decimal_notation">dotted-quad notation</a> for an IP v4 address; for instance, <span style="color: #9b00d3; font-family: Courier New;">http://127.0.0.1/mypage</span>. The introduction of IPv6 complicated matters a bit, since IPv6 literals must be <a href="http://blogs.msdn.com/b/ie/archive/2007/02/20/ipv6-uris-in-ie7.aspx">placed within square-brackets</a> in the URL, like so: <span style="color: #9b00d3; font-family: Courier New;">http://[::1]/mypage</span>. Many users are surprised, however, to learn that IPv4 literals can be expressed using other notations.</p>
<p>For instance, any internal &ldquo;<span style="color: #9b00d3; font-family: Courier New;">0</span>&ldquo; components of a dotted quad may be omitted, and thus <span style="color: #9b00d3; font-family: Courier New;">http://127.0.1</span> and <span style="font-family: Courier New;"><span style="color: #9b00d3;">http://127.1</span> </span>are both equivalent to <span style="color: #9b00d3; font-family: Courier New;">http://127.0.0.1</span>.</p>
<p>The more interesting of the notations are the raw integer forms&mdash;remember, an IPv4 address is simply a 32bit integer. As such, you can represent <span style="color: #9b00d3; font-family: Courier New;">127.0.0.1</span> in its decimal form as <span style="color: #9b00d3; font-family: Courier New;">http://2130706433/</span> or even in octal form as <span style="color: #9b00d3; font-family: Courier New;">http://017700000001/</span>. The reason that these variants are interesting is that they don&rsquo;t contain any dots, and various software components may treat hostnames without dots as <em>special</em><sup>1</sup>. In 2001, for instance, incorrect mapping of <em>all </em>dotless hostnames to the (privileged) <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/06/05/the-local-intranet-security-zone.aspx">Intranet security zone</a> resulted in a serious <a href="http://technet.microsoft.com/en-us/security/bulletin/ms01-051">security vulnerability</a> which was patched by introducing special detection for IP address literals.</p>
<p>In Internet Explorer 7, the <a href="http://blogs.msdn.com/b/ie/archive/2005/08/15/452006.aspx">CURI object</a> was introduced to standardize handling of URLs throughout the browser and OS; one of the first steps that class undertakes when constructing a URL object from a string is to convert any IP literal hostname into its canonical dotted-quad form. Chrome and Opera appear to match Internet Explorer&rsquo;s behavior here, while Firefox 27 leaves the undotted decimal in the address bar and in the request sent to the network<sup>2</sup>:</p>
<blockquote>
<p><strong><span style="text-decoration: underline;">IE, Chrome, Opera</span></strong></p>
<span style="color: #0000ff;">GET / HTTP/1.1 <br />Host: <span style="background-color: #ffff00;">127.0.0.1</span> <br />User-Agent: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.45 Safari/537.36</span>
<p><strong><span style="text-decoration: underline;">Firefox</span></strong></p>
<span style="color: #0000ff;">GET / HTTP/1.1<br />Host: <span style="background-color: #ffff00;">2130706433</span> <br />User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0</span></blockquote>
<p>If your code makes any sort of security decision based on the absence of dots within a hostname, be sure that you aren&rsquo;t fooled by undotted IP literals!</p>
<p>-Eric</p>
<p><sup>1</sup><span style="font-size: xx-small;"> For instance, the <span style="font-family: Courier New;">isPlainHostName</span> function in </span><a href="http://blogs.msdn.com/b/ieinternals/archive/2013/10/11/web-proxy-configuration-and-ie11-changes.aspx"><span style="font-size: xx-small;">PAC scripts</span></a><span style="font-size: xx-small;">, or the <span style="font-family: Courier New;">network.automatic-ntlm-auth.allow-non-fqdn</span> preference in Firefox.</span></p>
<p><sup>2</sup><span style="font-size: xx-small;"> Mozilla has </span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=67730"><span style="font-size: xx-small;">an issue filed</span></a><span style="font-size: xx-small;"> to remove support for undotted IP literals entirely, and while it&rsquo;s tagged as &ldquo;<strong>New</strong>,&rdquo; it is today just over 13 years old.</span></p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10505853" width="1" height="1">SecuritynetworkinginteropThere’s never magic, but plenty of butterfly effectshttp://blogs.msdn.com/b/ieinternals/archive/2014/02/26/internet-explorer-11-on-windows-8.1-rc4-deprecation-caused-nginx-openssl-proxy-to-truncate-post-body.aspxWed, 26 Feb 2014 18:13:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10503441EricLaw [ex-MSFT]0http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10503441http://blogs.msdn.com/b/ieinternals/archive/2014/02/26/internet-explorer-11-on-windows-8.1-rc4-deprecation-caused-nginx-openssl-proxy-to-truncate-post-body.aspx#comments<p>I&rsquo;ve always enjoyed magic shows, but I&rsquo;ve never attempted to understand how the tricks are performed, since that would take all of the fun out of them. In contrast, if I see a web browser demonstrating seemingly magical <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx">behavior</a> or <a href="http://blogs.msdn.com/b/ie/archive/2005/03/12/394526.aspx">misbehavior</a>, I find it hard to sleep until I figure out what&rsquo;s going on.</p>
<p>Earlier this month, a new phenomenon was reported that defied easy explanation. A customer posted a comment on this blog noting that her ASP.NET-based web application isn&rsquo;t working correctly over HTTPS in Internet Explorer 11 on Windows 8.1. With that combination, clicking a button on the site doesn&rsquo;t correctly load the next page -- doing so instead refreshes the current page. Putting the site in Compatibility View or the Trusted Zone didn&rsquo;t help at all. Her site works fine in other browsers on Windows 8.1 and it works fine in IE11 on Windows 7. It works fine when accessed over HTTP rather than HTTPS. More interestingly, it works fine even on W8.1 when Fiddler is running, or when the site is in her Intranet zone.</p>
<p>This was a strange combination indeed, and figuring out the hidden <em>X</em>-factor took a bit of sleuthing. At first, I was a bit stymied because <a href="http://fiddler2.com/">Fiddler</a> is my &ldquo;go-to&rdquo; debugger, and if it was causing the change in behavior, I couldn&rsquo;t use it.</p>
<p>Or could I? The fact that Fiddler changes behavior is an important clue. As I noted over in &ldquo;<a href="http://blogs.telerik.com/fiddler/posts/13-02-28/help!-running-fiddler-fixes-my-app-">Help! Running Fiddler fixes my app???</a>&rdquo; there are only a small set of changes that occur when Fiddler is used to monitor traffic. My first guess was that the HTTPS cipher in use changed when Fiddler was in HTTPS decryption mode (because Fiddler defaults to a max of TLS/1.0 while IE11 enables TLS/1.2 by default). After disabling HTTPS Decryption in Fiddler, IE used TLS1.2 through to the site but to my great surprise, the problem still vanished.</p>
<p>Curiouser and curiouser.</p>
<p>Fortunately, I recently added support in Fiddler for importing raw packet captures collected using <a href="http://fiddler2.com/r/?netmon">Microsoft Network Monitor</a> or <a href="http://www.wireshark.org/">WireShark</a>. While HTTPS traffic is encrypted and cannot be seen, I could use Fiddler to easily compare the HTTPS handshakes between the packet captures of the working (Fiddler or Intranet) and non-working scenarios.</p>
<p>And I found something quite interesting indeed.</p>
<h2>Here there be Butterflies</h2>
<p>The last few years have seen a number of <a href="http://googleonlinesecurity.blogspot.co.uk/2013/11/a-roster-of-tls-cipher-suites-weaknesses.html">new and improved attacks</a> against the algorithms used in securing HTTPS traffic, and as a consequence, last November, the IE team announced a change to <a href="http://blogs.msdn.com/b/ie/archive/2013/11/12/ie11-automatically-makes-over-40-of-the-web-more-secure-while-making-sure-sites-continue-to-work.aspx">reduce the use of RC4</a> for HTTPS connections.</p>
<p>By default, Internet Explorer 11 on Windows 7 offers the following ciphers in its first ClientHello TLS message:</p>
<p><strong>Windows 7 IE11 Default</strong></p>
<p><span style="font-family: Courier New;">&nbsp; [003C]&nbsp;&nbsp;&nbsp; TLS_RSA_WITH_AES_128_CBC_SHA256 <br />&nbsp; [002F]&nbsp;&nbsp;&nbsp; TLS_RSA_AES_128_SHA <br />&nbsp; [003D]&nbsp;&nbsp;&nbsp; TLS_RSA_WITH_AES_256_CBC_SHA256 <br />&nbsp; [0035]&nbsp;&nbsp;&nbsp; TLS_RSA_AES_256_SHA <br /><strong>&nbsp; [0005]&nbsp;&nbsp;&nbsp; SSL_RSA_WITH_RC4_128_SHA</strong> <br />&nbsp; [000A]&nbsp;&nbsp;&nbsp; SSL_RSA_WITH_3DES_EDE_SHA <br />&nbsp; [C027]&nbsp;&nbsp;&nbsp; TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 <br />&nbsp; [C013]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA <br />&nbsp; [C014]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA <br />&nbsp; [C02B]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 <br />&nbsp; [C023]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 <br />&nbsp; [C02C]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 <br />&nbsp; [C024]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 <br />&nbsp; [C009]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA <br />&nbsp; [C00A]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA <br />&nbsp; [0040]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 <br />&nbsp; [0032]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_128_SHA <br />&nbsp; [006A]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 <br />&nbsp; [0038]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_256_SHA <br />&nbsp; [0013]&nbsp;&nbsp;&nbsp; SSL_DHE_DSS_WITH_3DES_EDE_SHA <br /><strong>&nbsp; [0004]&nbsp;&nbsp;&nbsp; SSL_RSA_WITH_RC4_128_MD5</strong></span></p>
<p>By default, IE11 omits the RC4 ciphers from the offered ciphers when running on Windows 8.1:</p>
<p><strong>Windows 8.1 IE11 Default</strong></p>
<p><span style="font-family: Courier New;">&nbsp; [003C]&nbsp;&nbsp;&nbsp; TLS_RSA_WITH_AES_128_CBC_SHA256 <br />&nbsp; [002F]&nbsp;&nbsp;&nbsp; TLS_RSA_AES_128_SHA <br />&nbsp; [003D]&nbsp;&nbsp;&nbsp; TLS_RSA_WITH_AES_256_CBC_SHA256 <br />&nbsp; [0035]&nbsp;&nbsp;&nbsp; TLS_RSA_AES_256_SHA <br />&nbsp; [000A]&nbsp;&nbsp;&nbsp; SSL_RSA_WITH_3DES_EDE_SHA <br />&nbsp; [C027]&nbsp;&nbsp;&nbsp; TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 <br />&nbsp; [C013]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA <br />&nbsp; [C014]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA <br />&nbsp; [C02B]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 <br />&nbsp; [C023]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 <br />&nbsp; [C02C]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 <br />&nbsp; [C024]&nbsp;&nbsp;&nbsp; TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 <br />&nbsp; [C009]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA <br />&nbsp; [C00A]&nbsp;&nbsp;&nbsp; TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA <br />&nbsp; [0040]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 <br />&nbsp; [0032]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_128_SHA <br />&nbsp; [006A]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 <br />&nbsp; [0038]&nbsp;&nbsp;&nbsp; TLS_DHE_DSS_WITH_AES_256_SHA <br />&nbsp; [0013]&nbsp;&nbsp;&nbsp; SSL_DHE_DSS_WITH_3DES_EDE_SHA</span></p>
<p>However, if you are <strong>behind a proxy</strong> server (like Fiddler) or if the target site is in your <strong>Intranet Zone</strong> (not the Internet or Trusted Zones), then the RC4 ciphers are again offered in the ClientHello:</p>
<p><strong>Windows 7/8.1 IE11 Behind Proxy or Intranet</strong> <br /><span style="font-family: Courier New;">&nbsp; <span style="color: #a5a5a5;">&nbsp; Same as Win7 IE11 default, above.</span></span></p>
<p>This &ldquo;offer RC4 to proxies or private networks&rdquo; behavior was introduced for legacy compatibility reasons; because the IE team cannot &ldquo;see&rdquo; your Intranet sites or proxy server, they can&rsquo;t workaround any compatibility problems occurring on a private network by using a Compatibility View list update or similar mechanism.</p>
<p>And now we&rsquo;ve found the clearest difference between the working and non-working cases: <em>when the browser offers RC4, the site works, and when it doesn&rsquo;t, the site doesn&rsquo;t work.</em></p>
<p>Now that I understood the difference in behavior, I could use Fiddler to explore it more fully. Using a registry key, I manually disabled the use of RC4 by all components that use SChannel (e.g. WinINET, WinHTTP, System.NET etc). Save the following as <span style="font-family: Courier New;">NoRC4.reg</span> and import it using the Registry Editor:</p>
<p><span style="color: #0000ff; font-family: Courier New;">Windows Registry Editor Version 5.00</span></p>
<p><span style="color: #0000ff; font-family: Courier New;">[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128] <br />"Enabled"=dword:00000000</span></p>
<p><em>Note that this change is likely to break applications and at this time probably should only be used for testing purposes.</em></p>
<p>With RC4 disabled in this way, I could easily reproduce the problem even with Fiddler running or decrypting traffic. Using Fiddler&rsquo;s Compare feature, I first confirmed that the server was returning exactly the same bytes to the client as it downloaded the page. I then confirmed that the client was sending exactly the same HTTP POST body when the user clicked the button that triggered the ASP.NET postback.</p>
<p>So, the same content, sent over connections secured using different ciphers, behaved differently.</p>
<p>Fortunately, in playing with the site, a few other clues came to light. I noticed that the HTTP response&rsquo;s <strong>Server </strong>header claimed that the site was served by <strong>nginx</strong>, an interesting result for a site using ASP.NET. I asked the developer about her topology, and she explained that that they have an nginx/1.2.6 server acting as a HTTPS frontend (using OpenSSL 1.0.0f 4 Jan 2012) it is distributing requests to IIS servers on the backend.</p>
<p>While debugging the site under Fiddler, I noticed that occasionally one of its requests would cause a malformed response that looked like an attempt to send a <strong>HTTP/400 Bad Request </strong>status to the client.</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3730.image_5F00_42D8B01E.png" alt="image" width="354" height="140" border="0" /></p>
<p>And now I had a theory. The POST sent by the client had a 2kb body that contained the ViewState and, at the end, a parameter which was used to generate the URL to which the browser should be navigated. If I did nothing, or set a breakpoint and manually stripped out that parameter, the server would simply return the same page again. If, however, I padded the POST body with a trailing string of dummy (but well-formed) content, the server would correctly send the user to the next page.</p>
<p>My current theory is that the outdated nginx/OpenSSL combination in use here is failing to read the entire POST body from the browser client and, as a consequence, it&rsquo;s passing an incomplete POST to the backend server. The backend server, upon receiving incomplete postback data, simply returns the same page again. The nginx instance then attempts to parse the prematurely truncated end of the first POST&rsquo;s body as the beginning of a subsequent request on the connection, determines that it isn&rsquo;t valid HTTP traffic, and returns a HTTP/400. However, when the postback is padded with dummy data, only some portion of that dummy data is truncated, and the IIS server sees the parameters it needs and sends the proper response to the client.</p>
<p>Now, what could cause the nginx/OpenSSL combo here to have this problem with the <span style="font-family: Courier New;">TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</span> cipher combination? My guess is that it&rsquo;s a beast of a bug. More specifically, at the end of 2011, an attack named <a href="http://vnhacker.blogspot.com/2011/09/beast.html">BEAST</a> targeted CBC cipher algorithms, and as a consequence, browsers implemented a technique called <em>1/n-1 record splitting</em>, in which HTTPS traffic sent over CBC-based algorithms is split into multiple records. My current guess is that the older version of the frontend&rsquo;s software isn&rsquo;t properly collecting all of the records which represent the POST body, and as a consequence it&rsquo;s sending incomplete data to the backend server.</p>
<p>I&rsquo;ve suggested that the site owner update the frontend to use the very latest nginx and OpenSSL to see whether the problem is resolved.</p>
<p>In a decade of looking at browsers, I&rsquo;ve yet to find any magic, but there are plenty of cases where minor quirks, accumulated over decades and across billions of scenarios, lead to butterfly effects that are difficult to explain.</p>
<p>-Eric Lawrence <br />Internet Explorer MVP</p>
<p>PS: Good references on controlling SChannel via the registry: <a href="http://blogs.technet.com/b/askds/archive/2011/05/04/speaking-in-ciphers-and-other-enigmatic-tongues.aspx" rel="nofollow" target="_new">blogs.technet.com/.../speaking-in-ciphers-and-other-enigmatic-tongues.aspx</a>&nbsp;and <a href="http://support.microsoft.com/kb/245030/en-us">http://support.microsoft.com/kb/245030/en-us</a></p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10503441" width="1" height="1">Securityhttpsproblemsinterop“Everybody Lies”http://blogs.msdn.com/b/ieinternals/archive/2014/02/19/internet-explorer-and-everybody-else-version-lies-for-compatibility.aspxWed, 19 Feb 2014 17:02:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10501520EricLaw [ex-MSFT]2http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10501520http://blogs.msdn.com/b/ieinternals/archive/2014/02/19/internet-explorer-and-everybody-else-version-lies-for-compatibility.aspx#comments<p>Today we present EricLaw&rsquo;s 2nd law of Software:<span style="color: #0000ff;"> &ldquo;<em>If your software platform is sufficiently popular, and it offers a GetVersion API, that API probably lies.</em>&rdquo;</span></p>
<p>Recently, a user of Telerik&rsquo;s automated web testing product (<a href="http://www.telerik.com/teststudio">Test Studio</a>) filed a bug noting that they&rsquo;d recently upgraded their machines to IE11, but the test tool&rsquo;s GUI claimed that agents would be running IE9. Looking closer, the test agent actually indicated that it would use a non-existent version, <strong>IE 9.11</strong>.</p>
<p><em>How did that happen?</em></p>
<p>The agent client software checked the machine&rsquo;s registry to determine the current IE version. Following common and decades-old practice, the code simply looked at the <span style="font-family: Courier New;">Version</span> subkey inside <span style="font-family: Courier New;">HKLM\Software\Microsoft\Internet Explorer</span>. If you open RegEdit on a Windows 8.1 machine, the problem is immediately obvious:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/2818.image_5F00_236BFED7.png" alt="image" width="718" height="273" border="0" /></p>
<p>As you can see, the <span style="font-family: Courier New;">Version</span> key contains a bogus IE version: <span style="font-family: Courier New;">9.<strong>11</strong>.9600.16476</span>. On a Windows 8 machine running IE10, the <span style="font-family: Courier New;">Version</span> key contains <span style="font-family: Courier New;">9.<strong>10</strong>.9200.16384</span>.</p>
<p><em>So, the Version registry key lies. But why?</em></p>
<p>The Version key has lied since IE10 because there&rsquo;s a common and decades-old practice of looking in the registry to retrieve the IE version. Unfortunately, much of the code that does so is inside product installers that refuse to proceed if a minimal target IE version (e.g. 6+) isn&rsquo;t found. And that crusty old code never imagined there would one day exist a world in which IE&rsquo;s major version was more than a single digit long. As a consequence, when IE10+ is installed, many products would refuse to install and users would receive bizarre and inaccurate error messages (&ldquo;<em>Internet Explorer 6 is required. This system only has Internet Explorer 1.</em>&rdquo;).</p>
<p>After examining the broad scope of the compatibility problem, the team decided to change the registry format such that the &ldquo;true&rdquo; IE version would be preceded by a leading &ldquo;<span style="font-family: Courier New;">9.</span>&rdquo; to accommodate buggy version checkers. This approach generally worked well, but will confuse any software, like Test Studio, that was written prior to the version lie being introduced.</p>
<p>This is only one of many version lies.</p>
<h2>User-Agent Lies</h2>
<p>The most notorious of the version lies can be found in the browser&rsquo;s user-agent string. Consider the following simplistic application which hosts the Internet Explorer Web Browser control (WebOC):</p>
<p><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/1351.image_5F00_751509DA.png" alt="image" width="539" height="273" border="0" /></p>
<p>The browser first claims to be &ldquo;<span style="font-family: Courier New;">Mozilla/4.0</span>&rdquo;, a lie carried over from the mid-1990s when Netscape Navigator had overwhelming marketshare and every other browser needed to mimic it in order to have a chance of rendering important sites. Today, virtually all browsers claim to be a variant of Mozilla, although most modern browsers (Firefox, Chrome, IE11, etc) purport to be&nbsp; &ldquo;<span style="font-family: Courier New;">Mozilla/5.0</span>&rdquo;. By default, WebOC hosts run in IE7 Emulation mode, which is why you see both&nbsp; &ldquo;<span style="font-family: Courier New;">Mozilla/4.0</span>&rdquo; and &ldquo;<span style="font-family: Courier New;">MSIE 7.0</span>&rdquo; in the string; the <span style="font-family: Courier New;">Trident/7.0</span> token reveals the control&rsquo;s <em>true</em> nature. Only if the <a href="http://msdn.microsoft.com/en-us/library/ie/ee330730(v=vs.85).aspx">FEATURE_BROWSER_EMULATION</a> feature control key is set for the WebOC&rsquo;s host executable will the control default to a later emulation mode. Unlike IE itself, WebOCs do not use the downloaded Microsoft Compatibility View list (which can <a href="http://blogs.msdn.com/b/ieinternals/archive/2013/09/21/internet-explorer-11-user-agent-string-ua-string-sniffing-compatibility-with-gecko-webkit.aspx">offer site-specific UA string lies</a> for compatibility).</p>
<p>The&nbsp; &ldquo;<span style="font-family: Courier New;">Windows NT 6.2</span>&rdquo; token is another interesting one&mdash;it lies in numerous ways. First, Windows hasn&rsquo;t used the &ldquo;NT&rdquo; moniker since Windows 2000 was released. Next, my application is running on Windows 8.1, and yet the UA string claims that Windows is v6.2. That&rsquo;s a lie stacked on top of a lie. With Windows Vista&rsquo;s release, the Major version returned by <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx">GetVersionEx</a> has been frozen at <span style="font-family: Courier New;">6</span>; Windows Vista was <span style="font-family: Courier New;">6.0</span>, Windows 7 was <span style="font-family: Courier New;">6.1</span>, Windows 8 was <span style="font-family: Courier New;">6.2</span>, and Windows 8.1 was <span style="font-family: Courier New;">6.3</span>. So, even considering the <span style="font-family: Courier New;">6.x</span> lie, you&rsquo;d expect that my test application would be showing 6.3, but it&rsquo;s not.</p>
<p>That&rsquo;s because <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx">GetVersionEx</a> now directly lies to applications that call it when run on Windows 8.1; it only returns the <span style="font-family: Courier New;">6.3</span> value if the application specifically indicates compatibility with 8.1 inside <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dn481241(v=vs.85).aspx">its manifest</a>. To prevent <em>applications</em> from lying (and, say, claiming compatibility with Windows 9 before it exists), the manifest requires that callers list their supported operating systems using a GUID; each OS version&rsquo;s GUID is only documented when the new OS version is reaches its public preview stages.</p>
<p>Windows&rsquo; <a href="http://www.microsoft.com/en-us/download/details.aspx?id=20028">AppVerifier tool</a> has long offered developers a means to test whether software is inappropriately limiting itself based on the Windows version; when the <strong>HighVersionLie </strong>test is enabled, the application being verified will receive a high (and fake) version number when calling GetVersionEx; in this case, Windows claims to be version <span style="font-family: Courier New;">8.5.1060</span><span style="font-family: Courier New;">0</span>:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7230.image_5F00_2229F6A9.png" alt="image" width="748" height="293" border="0" /></p>
<p>Unfortunately, not enough applications test with AppVerifier and many still inappropriately perform version checks. In Internet Explorer, we even found that some <em>websites </em>would fail; when Windows Vista was in development, for instance, the TurboTax website refused to load because it didn&rsquo;t like the <span style="font-family: Courier New;">Windows NT 6.0</span> version token.</p>
<h2>API Lies</h2>
<p>Many other versioning APIs will also return bogus results for compatibility.</p>
<p>For instance, when updating Fiddler to support the new <a href="http://stackoverflow.com/a/5138232/126229">SmartWPAD</a> feature introduced in Internet Explorer 8, I figured I&rsquo;d ask WinINET for its version information before using IE8&rsquo;s new INTERNET_PER_CONN_FLAGS_UI flag (since this flag isn&rsquo;t supported by earlier versions of WinINET).</p>
<p>For this task, I expected I&rsquo;d use simply call <span style="font-family: Courier New;">InternetQueryOption(</span><span style="font-family: Courier New;">INTERNET_OPTION_VERSION)</span> and look at the resulting version. Unfortunately, as I soon discovered, this call&rsquo;s return value was frozen at <span style="font-family: Courier New;">1.2</span> in the mid-1990s. In talking to the developers, I learned that this value was also frozen due to compatibility concerns, where applications refused to run on later versions.</p>
<p>To reliably use the INTERNET_PER_CONN_FLAGS_UI flag, you must simply check the return value of the <span style="font-family: Courier New;">InternetQueryOption</span> call, and if it returns <span style="font-family: Courier New;">ERROR_INVALID_PARAMETER</span>, retry the call without the flag.</p>
<h2>Random Lies and Failures to Lie</h2>
<p>You need only peruse this blog to find other cases where version information either already lies, or should do a better job of lying:</p>
<ul>
<li>The SSL/TLS version communicated during a HTTPS handshake is a bit of a lie (e.g. TLS1.0 is advertised as SSLv3.1), but some servers still <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/03/25/misbehaving-https-servers-impair-tls-1.1-and-tls-1.2.aspx">unexpectedly fail</a> when they see a version number that they don&rsquo;t expect, rather than simply using the latest protocol version they do support.</li>
<li>For years, the default guidance for Apache would result in disabling keep-alive for any IE version &lt;5 and &gt;9, as I described <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/03/26/https-and-connection-close-is-your-apache-modssl-server-configuration-set-to-slow.aspx">here</a>.</li>
<li>The <a href="http://dom.spec.whatwg.org/#dom-document-compatmode">compatMode property</a> is frozen at CSS1.</li>
<li>&hellip;</li>
</ul>
<h2>Other Browsers</h2>
<p>Cynical observers everywhere might remark: &ldquo;No, only Microsoft products lie,&rdquo; but this is, of course, untrue.</p>
<ul>
<li>Opera was the first browser to include a robust system of compatibility lies</li>
<ul>
<li>With its small marketshare, it was forced to emulate many IE proprietary features so it would be detected as a supported browser</li>
<li>It was the first major browser to cross the two-digit version boundary; the User-Agent string remains frozen at Opera/9.8</li>
<li>It was the first major browser with a &ldquo;Compat list&rdquo; that was downloaded to the client with site-specific lies</li>
</ul>
<li>Firefox&rsquo;s User-Agent header contains several lies, including the frozen string <span style="font-family: Courier New;">Gecko/20100101</span>&nbsp;</li>
<li>Firefox&rsquo;s extension model requires that extensions declare their minimum and maximum supported version; unlike the Windows versioning APIs, the numbers used are entirely predictable and nothing stops extensions declaring compatibility with some <em>future </em>version of the platform. Such lies became a necessity as the Firefox shipping cycle accelerated.</li>
<li>Chrome&rsquo;s User-Agent string is designed to spoof Netscape, Firefox, Safari, and KHTML simultaneously. Having said that, Chrome has been generally successful in shipping new versions as such a frenetic pace that any site that attempts to target a <em>specific </em>Chrome version will likely be broken before the development team manages to push their bits to the server.</li>
</ul>
<p>Everybody lies. It&rsquo;s usually for good reason, to accommodate someone else&rsquo;s bad code. Please follow best practices like feature detection, and do your best to write future-proof code.</p>
<p>Thanks!</p>
<p>-Eric</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10501520" width="1" height="1">Best-PracticeswebocwininetrantsinteropDebugging Internet Explorer - A Beginner’s Guidehttp://blogs.msdn.com/b/ieinternals/archive/2014/01/15/debugging-internet-explorer-with-windbg.aspxWed, 15 Jan 2014 20:17:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10490056EricLaw [ex-MSFT]0http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10490056http://blogs.msdn.com/b/ieinternals/archive/2014/01/15/debugging-internet-explorer-with-windbg.aspx#comments<p><em>As a Program Manager on the IE team, I spent comparatively little time running Internet Explorer under the debugger. In contrast, the IE developers were far more adept at solving problems with advanced debugging techniques. Nevertheless, over the years I picked up a few tricks that proved useful from time-to-time. In this post, I outline some of the simpler ways to use WinDbg to get useful information about failures in IE.</em></p>
<p>When your webpage&rsquo;s scripts fail, your first step should be to hit F12 and go to the Script Debugging tab to see what went wrong. However, if IE itself crashes or hangs, the F12 Developer Tools probably can&rsquo;t help you&mdash;you&rsquo;ll need a native debugger. Native debuggers can be quite a bit more complicated to use than IE&rsquo;s script debugger; even if you have IE&rsquo;s source code, native code debugging is simply more complicated than script debugging. Also, unlike with a script bug, you&rsquo;re unlikely to be able to fix IE itself (unless you find that the crash is due to a buggy browser extension, in which case you could update it or uninstall it).</p>
<p>Debugging Internet Explorer can be somewhat more complicated than other programs because:</p>
<ul>
<li>There are multiple processes involved. Typically, there&rsquo;s at least one Frame/Manager process (which hosts the tabs and main window) and one or more Tab/Content processes (which host the HTML and script). This split is called <a href="http://blogs.msdn.com/b/ie/archive/2008/03/11/ie8-and-loosely-coupled-ie-lcie.aspx">Loosely-Coupled IE</a>.</li>
<li>Internet Explorer is available in both 32bit and 64bit versions. In modern IE versions, the Frame process is 64bit and the Tab processes will be either 32bit or 64bit depending on the configuration.</li>
</ul>
<p>However, don&rsquo;t despair&mdash;with the tips below, you can explore Internet Explorer under the debugger.</p>
<h2>Install WinDbg</h2>
<p>First, download the Debugging Tools for Windows. You&rsquo;ll probably want to install the 64bit version as well as the 64bit version, unless you happen to be debugging on a 32bit version of Windows in which case you can simply install the 32bit version. Typically, I install the 64bit version to<span style="color: #0000ff; font-family: Courier New;"> C:\dbg64\</span> and the 32bit version to <span style="color: #0000ff; font-family: Courier New;">c:\dbg32\</span></p>
<h1>Configure the Post-Mortem Debugger</h1>
<p>You can configure Windows to launch WinDbg whenever a process crashes by setting it as the <em>post-mortem debugger</em>.</p>
<ol>
<li>From an elevated 64bit instance of<span style="color: #0000ff;"> c:\windows\system32\cmd.exe</span>, run <span style="color: #0000ff; font-family: Courier New;">c:\dbg64\WinDbg.exe -I</span> to configure WinDbg as the default post-mortem debugger for 64bit process crashes.</li>
<li>Then, from an elevated <strong>32-bit</strong> instance of<span style="color: #0000ff;"> c:\windows\syswow64\cmd.exe</span>, run <span style="color: #0000ff; font-family: Courier New;">c:\dbg32\WinDbg.exe &ndash;I </span>to set the post-mortem debugger for 32bit processes.</li>
</ol>
<p>Note that the <span style="color: #0000ff; font-family: Courier New;">-I</span> parameter must be in uppercase. When the command succeeds, WinDbg will show the following notice:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/4064.image_5F00_74AE8767.png" alt="image" width="445" height="172" border="0" /></p>
<h1>Manually Attaching</h1>
<p>Of course, you may want to attach the debugger to an existing or new browser instance that hasn&rsquo;t crashed. To attach to an existing instance, launch WinDbg and click <strong>File</strong> &gt;<strong> Attach to a Process</strong> and select the <span style="color: #0000ff; font-family: Courier New;">iexplore.exe</span> instance of interest.</p>
<p>Alternatively, you can start a new instance to debug by clicking <strong>File</strong> &gt;<strong> Open Executable </strong>and selecting <span style="color: #0000ff; font-family: Courier New;">C:\Program Files\Internet Explorer\iexplore.exe</span>. Be sure to check the <strong>Debug child processes also </strong>box at the bottom of the Open Executable screen, so that you attach to both the Frame/Manager process and the Tab/Content processes.</p>
<p>Tip: To simplify things, before attaching, close all browser instances that are not being debugged.</p>
<h1>Symbols</h1>
<p>Debuggers aren&rsquo;t much fun if they don&rsquo;t have the &ldquo;symbol&rdquo; information which maps binary offsets back to functions. Unfortunately, you aren&rsquo;t likely to have access to the &ldquo;private symbols&rdquo; available to the IE development team, but you can configure WinDbg to automatically download and cache the &ldquo;public symbols&rdquo; as follows:</p>
<blockquote>
<p><strong>32bit debugger</strong></p>
<p><span style="font-size: small;"><span style="color: #0000ff; font-family: Courier New;">.sympath SRV*C:\dbg32\symbols*</span><a href="http://msdl.microsoft.com/download/symbols"><span style="color: #0000ff; font-family: Courier New;">http://msdl.microsoft.com/download/symbols</span></a><span style="color: #0000ff; font-family: Courier New;">; .reload</span></span></p>
<p><strong>64bit debugger</strong></p>
<p><span style="font-size: small;"><span style="color: #0000ff; font-family: Courier New;">.sympath SRV*C:\dbg64\symbols*</span><a href="http://msdl.microsoft.com/download/symbols"><span style="color: #0000ff; font-family: Courier New;">http://msdl.microsoft.com/download/symbols</span></a><span style="color: #0000ff; font-family: Courier New;">; .reload</span></span></p>
</blockquote>
<h1>Next Steps</h1>
<p>When using the 64bit debugger to debug a 32bit process, you&rsquo;ll find that all of the stacks are &ldquo;mangled&rdquo; with <span style="font-family: Courier New;">wow64</span> virtualization function calls. To fix them, first execute:</p>
<blockquote>
<p><span style="color: #0000ff; font-family: Courier New;">.load wow64exts </span></p>
</blockquote>
<p>then</p>
<blockquote>
<p><span style="color: #0000ff; font-family: Courier New;">.effmach x86</span></p>
</blockquote>
<p>After using these commands, WinDbg will helpfully show you the 32-bit process&rsquo; information without the virtualization goo.</p>
<p>There are a huge number of commands you can use once you&rsquo;re in the debugger, but here are a few of the most useful:</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">!analyze -v</span> <br /></span>Performs analysis of an exception (e.g. to attempt to determine the origin and nature of a pending access violation crash).</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">!analyze -hang</span> <br /></span>Performs analysis of an hang.</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">!runaway</span> <br /></span>Shows you the amount of time each thread has spent on the CPU.</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">g</span> <br /></span>Resumes execution of all threads when stopped at a breakpoint.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">~<em><span style="background-color: #ffffff;">0</span></em>kp</span> <br /></span>Shows the stack trace and parameters to the functions on the stack for the thread number specified.</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">~*kp</span> <br /></span>Shows the stack trace and parameters to the functions on the stack for all threads. This command can be very helpful if, for instance, you&rsquo;ve broken into Internet Explorer while a dialog box is showing and you want to understand what led to that dialog box being shown.</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">.dump /ma C:\tmp\out.dmp</span> <br /></span>Creates a <a href="http://blogs.msdn.com/b/ieinternals/archive/2009/10/12/collecting-internet-explorer-crash-dumps.aspx">dump file</a> that can be used to diagnose a failure later, or from a different machine. Sharing a dump file with a developer is a great way to help them quickly find the source of a problem.</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">lm vm <em>partialfilename</em>*</span> <br /></span>Shows&nbsp; verbose information about the modules matching the specified search pattern.</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">bu <em>module!function</em></span> <br /></span>Creates a breakpoint for the target function; the debugger will break on each hit to that function.</p>
<p><span style="color: #0000ff; font-family: Courier New; font-size: x-small;"><span style="font-size: small;">.foreach(pid {|}){.if($spat("${pid}","[0-9]")|$spat("${pid}","[0-9][0-9]")){|${pid}s;<em>bu mshtml!fnName</em>}}</span> <br /></span>Runs the specified command (in this case <span style="color: #0000ff; font-family: Courier New;">bu mshtml!fnName</span>) in each process under debugging, not just the active one. This admittedly verbose syntax is useful when you would like to break whenever a specified function is hit by any process (Frame or Tab) currently loaded.</p>
<h1>Enhancing Failures with gFlags</h1>
<p>In some cases, you&rsquo;ll find that crashes seem to occur randomly, inconsistently, or far from the code being exercised. In such cases, the problem is often that <strong>heap corruption </strong>has occurred. The failing code corrupts memory used in other codepaths, which (potentially much later in execution) crash when the trashed data is accessed.</p>
<p>To help debug heap corruption issues, you can enable <strong>page heap</strong> for the target process. Page heap tags each heap request with additional metadata such that corruption is more likely to be discovered immediately&mdash;the process will halt with an exception at the point of the corruption.</p>
<p>To enable page heap, use the <span style="font-family: Courier New;">gflags.exe</span> tool that is included with the WinDbg installation.</p>
<p><img style="display: inline; background-image: none;" title="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/0383.image_5F00_0D3E24B8.png" alt="image" width="550" height="543" border="0" /></p>
<p>Page heap has relatively little overhead in most situations, but scenarios which result in many small allocations can be impacted, so you&rsquo;ll generally want this flag set only when debugging.</p>
<h1>Other tools</h1>
<p>If you&rsquo;re trying to understand how IE interacts with the system, there are several powerful and useful tools to try:</p>
<ul>
<li><strong><a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">Process Explorer</a></strong> &ndash; Shows all processes on the system, as well as what files and handles they own.</li>
<li><strong><a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx">Process Monitor</a></strong> &ndash; Shows all registry and filesystem reads and writes. If you configure this tool using its <strong>Options</strong> &gt; <strong>Configure Symbols</strong> menu (point to the symbol path you set up above), it can show the stack trace at the point of each call.</li>
<li><strong><a href="http://www.rohitab.com/apimonitor">API Monitor</a></strong> &ndash; Shows all API calls made by the process.</li>
</ul>
<p>If you&rsquo;re trying to see how IE interacts with the Network, the F12 Developer Tools&rsquo; tab offers a basic view, and you can use <a href="http://fiddler2.com">Fiddler</a> to take a deeper look.</p>
<h1>Learning more&hellip;</h1>
<p>Recently, Microsoft&rsquo;s Tarik Soulami<strong>&nbsp;</strong>wrote a great end-to-end guide to debugging on Windows; you can get <a href="http://www.amazon.com/gp/product/0735662789/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0735662789&amp;linkCode=as2&amp;tag=baydensystems">Inside Windows Debugging</a> from Amazon or local bookstores.<strong> </strong>Highly recommended.</p>
<p>-Eric Lawrence</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10490056" width="1" height="1">toolstroubleshootingcrashdebugging“Continue” Link Missing from Certificate Error Page?http://blogs.msdn.com/b/ieinternals/archive/2013/12/12/ie-website-security-certificate-blocking-page-missing-continue-link.aspxThu, 12 Dec 2013 16:59:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10481591EricLaw [ex-MSFT]8http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10481591http://blogs.msdn.com/b/ieinternals/archive/2013/12/12/ie-website-security-certificate-blocking-page-missing-continue-link.aspx#comments<p>A user recently reported that IE11 wasn&rsquo;t showing the &ldquo;Continue&rdquo; link on the certificate error page shown when visiting their 2009-era router&rsquo;s configuration UI. They were curious why that link wasn&rsquo;t shown in this instance.</p>
<p>The error page&rsquo;s <strong>Continue</strong> link is hidden:</p>
<ol>
<li>If the certificate is revoked</li>
<li>If the certificate is deemed <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/06/13/windows-internet-explorer-block-rsa-key-shorter-than-1024-bits.aspx">insecure</a> (e.g. contains a 512-bit RSA&nbsp;key)</li>
<li>If the page is in <a href="http://blogs.msdn.com/b/ie/archive/2011/03/11/internet-explorer-9-security-part-3-browse-more-securely-with-pinned-sites.aspx">a &ldquo;pinned site&rdquo; instance</a></li>
<li>If group policy is set to Prevent Ignoring Certificate Errors</li>
</ol>
<p>In this case, #2 is the most likely.</p>
<p>Had the user provided a screenshot of the blocking page and the URL of the page (shown in right-click Properties, NOT the address bar) it would simplify troubleshooting of the issue. Similarly, providing the make/model of the router will allow contacting the vendor to request a firmware update.</p>
<p>Here's what you see if the server sends a certificate with a 512-bit RSA key:</p>
<p><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image[1]" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/3312.image1_5F00_4D14A17A.png" alt="image[1]" width="644" height="298" border="0" /></p>
<p>Old IE versions (prior to IE10) omitted the line <em>&ldquo;The security certificate presented by this website is not secure</em>&rdquo; and included the &ldquo;<em>Continue</em>&rdquo; link although clicking it was non-functional. IE10 <a href="http://blogs.msdn.com/b/ieinternals/archive/2012/06/13/windows-internet-explorer-block-rsa-key-shorter-than-1024-bits.aspx">fixed those shortcomings</a>. At the time that this page was designed, complaining about RSA key length specifically in the error page was deemed unlikely to help users, since they&rsquo;re rarely able to change the certificate a site uses.</p>
<p>Having said that, as a geek, I do like the page that Chrome shows:</p>
<p><a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/8623.image3_5F00_26491BEB.png"><img style="border: 0px currentcolor; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image[3]" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-47-13-metablogapi/7484.image3_5F00_thumb_5F00_6F0294AF.png" alt="image[3]" width="644" height="456" border="0" /></a></p>
<p>Firefox 26 doesn&rsquo;t care or warn about the weak certificate. In contrast, if&nbsp;a certificate with a&nbsp;strong key&nbsp;is signed with a weak hash (e.g. MD5), IE doesn't complain, but both Firefox and Chrome&nbsp;will block access to the site.</p>
<h2>Testing Weak Keys</h2>
<p>You may be wondering how you can easily see how your software behaves with weak keys. Doing so is very easy with <a href="http://fiddler2.com/">Fiddler</a> and its plugin <a href="http://fiddler2.com/r/?fiddlercertmaker">Certificate Generator</a>. After installing the add-on and enabling HTTPS decryption in Fiddler, type <span style="font-family: Courier New;"><span style="color: #0000ff;">prefs set fiddler.certmaker.bc.KeyLength 512</span> </span>in the black QuickExec box underneath the Web Sessions list. Hit Enter, and restart Fiddler. Subsequently, Fiddler will generate server certificates that use a 512 bit key. To later revert this configuration, either type <span style="color: #0000ff; font-family: Courier New;">about:config</span> in the QuickExec box and remove the preference using the UI, or type <span style="font-family: Courier New;"><span style="color: #0000ff;">prefs remove fiddler.certmaker.bc.KeyLength</span>&nbsp;</span>hit Enter, and restart Fiddler.</p>
<p>-Eric</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10481591" width="1" height="1">SecurityhttpscertificatefiddlerBetterInIE10What I’d like to see in IE12http://blogs.msdn.com/b/ieinternals/archive/2013/12/11/internet-explorer-12-wishlist-of-bug-fixes-and-new-features.aspxWed, 11 Dec 2013 17:31:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:10481255EricLaw [ex-MSFT]57http://blogs.msdn.com/b/ieinternals/rsscomments.aspx?WeblogPostID=10481255http://blogs.msdn.com/b/ieinternals/archive/2013/12/11/internet-explorer-12-wishlist-of-bug-fixes-and-new-features.aspx#comments<p>As the holidays approach, I&rsquo;ve decided to publish my &ldquo;wishlist&rdquo; for the next version of Internet Explorer. I&rsquo;ve been pretty good this year, so hopefully the IE team will deliver some of these presents. :-)</p>
<p><em>Please remember: I&rsquo;m just an MVP, and I don&rsquo;t have any magic powers that would guarantee that any of my wishes come true.</em></p>
<p><strong>Update:&nbsp;</strong>In April 2014, the IE team launched <a href="http://status.modern.ie">http://status.modern.ie</a>, which provides an overview of IE feature support including a roadmap for new feature implementation. You can add suggestions and vote on them using the <a href="https://wpdev.uservoice.com/forums/257854-internet-explorer-platform">WebPlatform UserVoice</a>&nbsp;and the <a href="https://windows.uservoice.com/forums/265757-feature-suggestions/category/87567-internet-explorer">Browser Interface UserVoice</a>.</p>
<p><strong><span style="text-decoration: underline;">New Feature Support</span></strong></p>
<p>1. <strong>HSTS</strong>: <a href="http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security">HTTP Strict-Transport-Security</a> is a relatively simple feature that allows a site to demand that all accesses take place over a secure (HTTPS) connection, with no certificate errors. This feature can be weakly emulated by pinning a site in IE8 or later, but that requires user-interaction and doesn&rsquo;t cover all scenarios. All major competitive browsers now <a href="http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security#Browser_support">support this feature</a>. <span style="color: #ff0000;"><strong>Update: <a href="http://status.modern.ie/httpstricttransportsecurityhsts">In Development</a> </strong></span></p>
<p>2. Support <strong>HTTP2.0 </strong>on Windows 7. Support for this newer/faster replacement for the aging HTTP/1.1 protocol was brought to Windows 8.1 with IE11 but IE 11 users on Windows 7 were left out, presumably due to the platform dependencies required to support the new protocol (e.g. it requires changes in SChannel to allow NPN/ALPN extensions in the TLS handshake).</p>
<p>For bonus points, I&rsquo;d love to see a way for .NET applications to be able to negotiate SPDY/HTTP2 connections (even if it requires a native PInvoke) as this would dramatically simplify adding support for these protocols to Fiddler.</p>
<p>3. <strong>Server-Sent-Events</strong>. SSE allows JavaScript to very simply collect and process a stream of messages from a server.&nbsp;The unidirectional stream&nbsp;is&nbsp;simpler than WebSockets and the programming model is convenient for JavaScript programmers. This feature overlaps others (e.g. XHR with streaming, WebSockets) and thus is just syntactic sugar, but it&rsquo;s <em>oh-so-tasty</em> syntactic sugar. <strong>Update:&nbsp;<a href="http://status.modern.ie/serversenteventseventsource">Under consideration</a> </strong></p>
<p>4. <strong>Developer Tools Support for P3P</strong>. Today, IE is the only browser that supports the <a href="http://blogs.msdn.com/b/ieinternals/archive/2013/09/17/simple-introduction-to-p3p-cookie-blocking-frame.aspx">P3P privacy-protection</a> standard, and as a consequence web developers often encounter problems with it. Today, IE's developer tools do not warn the developer if their cookies are being impacted by P3P and thus they often assume that IE is somehow &ldquo;broken&rdquo; when it is behaving as designed. Note: It would actually be great to see this for ALL security features; for instance, F12 could help debug problems where <a href="https://connect.microsoft.com/IE/feedback/details/871413/ie11-cannot-attach-a-picture-on-twitter-direct-messages">sites have been blocked by X-Frame-Options</a>. <strong>Update</strong>: P3P Appears to be gone entirely in Windows 10 Preview</p>
<p>5. <strong>Native Dictionary</strong>.<strong>&nbsp;</strong>IE added spell-checking in version 10, but the Kindle and Mac browsers have gotten me addicted to being able to quickly get a <em>definition</em> for any word on a webpage. The legacy Accelerators feature could have been a way to get this, but it requires configuration and is not nearly as seamless as the native feature in other products.</p>
<p>6. <strong>Preserve-3d </strong>support. Basically <a href="http://caniuse.com/transforms3d">everyone else supports this</a>, and the <a href="http://msdn.microsoft.com/en-us/library/ie/hh673529(v=vs.85).aspx">workarounds</a> for lack of support are awkward. <strong>Update: <a href="http://status.modern.ie/csstransformspreserve3d">In Development</a>, <span style="color: #ff0000;">Shipped in Win10 Preview</span></strong></p>
<p>7. An off-by-default option to disable (or require confirmation) of the use of the <strong>backspace key as a back button</strong>. Some users <em>hate </em>this feature (there are&nbsp;<a href="http://connect.microsoft.com/IE/feedback/details/791951/backspace-key-should-not-trigger-back-navigation#tabs">many bugs on CONNECT</a>) and even developers inside the IE team have complained that there's no way to turn this off. <a href="https://windows.uservoice.com/forums/265757-windows-feature-suggestions/suggestions/6513748-make-backspace-key-goes-back-optional">Tracked as UserVoice here</a>.</p>
<p>8. A UI option to enable warning the user if <strong>Certificate Revocation checks fail to complete</strong>. Today, <a href="https://blogs.msdn.com/b/ieinternals/archive/2011/04/07/enabling-certificate-revocation-check-failure-warnings-in-internet-explorer.aspx">incomplete checks are silent</a> and this makes certificate revocation checks unsuitable for handling key-compromise revocations like the many thousands of revocations caused by HeartBleed. By default, IE should also downgrade any EV site which does not complete revocation checks by removing the green bar.&nbsp;Beyond exposing the "Warn on revocation incomplete"&nbsp;option in the UI, IE/SChannel should support the <strong>MustStaple </strong>flag for certificates.</p>
<p><strong><span style="text-decoration: underline;">Bug Fixes</span></strong></p>
<p>1. When IE8 introduced the <strong>postMessage</strong> API, it had a <a href="http://blogs.msdn.com/b/ieinternals/archive/2009/09/16/bugs-in-ie8-support-for-html5-postmessage-sessionstorage-and-localstorage.aspx">bug</a> whereby you could not use the API to communicate between browser windows. This bug is now over four years old and is an interoperability problem. It needs to be fixed.</p>
<p>2. When IE8 introduced the <strong>localStorage </strong>API, it had a <a href="http://blogs.msdn.com/b/ieinternals/archive/2009/09/16/bugs-in-ie8-support-for-html5-postmessage-sessionstorage-and-localstorage.aspx">bug</a> whereby you could not use the API to share data between browser sessions. This bug is now over four years old and should be fixed.</p>
<p>3. Over the years, we thought we fixed most of the &ldquo;<em>Cannot SaveAs an image in its native format</em>&rdquo; bugs, and offered a <a href="http://blogs.msdn.com/b/ieinternals/archive/2010/09/15/ie9-beta-minor-change-list.aspx">&ldquo;Save As PNG&rdquo; option for the corner cases</a>. Recently, an IE user discovered that the SaveAs code cannot <a href="http://www.debugtheweb.com/test/images/fragmentInURL.htm">handle URL fragments in the image URL</a> and hits the fallback codepath unnecessarily. This should be an easy fix.</p>
<p>4. A customer recently uncovered a bug whereby, if a server sends two instances of a cookie on a single response (one a session cookie and one a persistent cookie) it&rsquo;s possible that <em>both </em>cookies will be immediately discarded (<a href="http://www.debugtheweb.com/test/cookie/dupe.aspx">test case</a>). This is clearly a corner case (servers shouldn&rsquo;t be doing this and should be fixed) but this should be straightforward to fix.</p>
<p>5. In IE10, we updated IE to behave like other browsers when following redirects when the original URL <a href="http://blogs.msdn.com/b/ieinternals/archive/2011/05/16/url-fragments-and-redirects-anchor-hash-missing.aspx">contained a fragment</a>. However, a corner-case was missed and IE10/IE11 do not behave the same as other browsers when a chain of two or more redirects is processed and one of the redirects in the middle introduces a URL fragment.</p>
<p>6. IE11 introduced a regression where <a href="http://webdbg.com/ie/InPrivateInfoDisc.htm">users InPrivate can be unmasked</a>. This is a regression from IE10 and should be fixed. <span style="color: #ff0000;"><strong>Update: </strong>This was quietly fixed in a monthly update.</span></p>
<p>7. IE10 introduced a regression <a href="https://connect.microsoft.com/IE/feedback/details/838086/internet-explorer-10-11-wininet-api-drops-proxy-change-events-during-system-shutdown">where proxy settings changes are lost</a>. This is very irritating for Fiddler users and impacts other customers too. Still repros in Windows 10 Preview.</p>
<p>I suspect I&rsquo;ll be adding to my wishlist over time. If you have succinct straightforward suggestions for additions, please sound off in the comments below!</p>
<p><span style="font-size: x-small;"><strong>Update: </strong>Below, Chris Love makes an important point:&nbsp;IE team has an official&nbsp;feedback mechanism at <a href="https://connect.microsoft.com/IE/feedback/CreateFeedbackForm.aspx?FeedbackFormConfigurationID=5534&amp;FeedbackType=1" rel="nofollow" target="_new">connect.microsoft.com</a>.&nbsp;Also, I'm not looking for a laundry list of "<em>Here's a bunch of proposal/spec&nbsp;hyperlinks, Go!</em>" The IE Engineers are aware of all of the popular sites (CanIUse, etc) and track virtually all of the public specifications. The point here is to&nbsp;provide feedback on the things that we think may have been overlooked, or which may be more important than they initially appear. The best suggestions explain <strong>why</strong> you think the feature in question is not only valuable, but more valuable than anything else with a similar development cost.</span></p>
<p>-Eric</p>
<p>PS: Perf Guru Steve Souders recently posted his <a href="http://calendar.perfplanet.com/2013/browser-wishlist-2013/">Browser Perf Wishlist</a>.</p><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=10481255" width="1" height="1">Securitylimitationsnetworkinginterop