<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>IEInternals</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/ieinternals/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/ieinternals/feed.xml</link>
    <description>A look at Internet Explorer from the inside out. @EricLaw left Microsoft in 2012, and rejoined Microsoft Edge in 2018.</description>
    <lastBuildDate>Fri, 17 Aug 2018 16:02:01 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Authenticode in 2015</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/authenticode-in-2015</link>
      <pubDate>Wed, 28 Jan 2015 12:34:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2015/01/28/authenticode-in-2015/</guid>
      <description><![CDATA[Back in 2011, I wrote a post explaining why and how software developers should use Authenticode to...]]></description>
      <content:encoded><![CDATA[<p>Back in 2011, I wrote a post explaining <a href="https://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="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/2388.image_48B700F6.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4314.image_thumb_605C8F41.png" original-url="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7080.image_637CCE0E.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7024.image_7232CA1A.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/8865.image_75BF3BDC.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/1220.image_1282F3B6.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4265.image_06810382.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/1157.image_1B065300.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/1663.image_thumb_2F8BA27E.png" original-url="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/8666.mychain.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/8666.mychain.png" original-url="https://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 "https://www.example.com/myApp/" -a sha1 -t https://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="https://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="https://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="https://www.cnet.com/news/adobe-to-revoke-code-signing-certificate/">configured</a> to <a href="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4621.hardware_71FE44B4.jpg" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4237.hardware_thumb_51770502.jpg" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3247.image_65FC5480.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/6724.image_0853E9FA.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/8461.image_2EB5CD45.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/2047.image_49EE2646.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/6747.image_332EDEBD.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3051.image_thumb_4094F1C3.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/8360.image_3BB23E07.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3404.image_6BDC197B.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/1856.image_6450AA0E.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/1362.image_58BAECCF.png" original-url="https://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 "https://www.example.com/myApp/" -a sha1 -t https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/8637.image_1B2D8F06.png" original-url="https://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 "https://www.example.com/myApp/" -a sha1 -t https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7266.image_5D33FE47.png" original-url="https://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>]]></content:encoded>
    </item>
    <item>
      <title>In Case You Missed It</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/in-case-you-missed-it</link>
      <pubDate>Tue, 27 Jan 2015 07:41:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2015/01/27/in-case-you-missed-it/</guid>
      <description><![CDATA[A random collection of noteworthy links:
Spartan PM Jacob Rossi wrote about the new Project Spartan...]]></description>
      <content:encoded><![CDATA[<p><em>A random collection of noteworthy links:</em></p>
<p>Spartan PM Jacob Rossi wrote about <a href="https://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="https://www.justrog.com/2015/01/code-dead-code-and-undead-code.html">tantalizing</a> <a href="https://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="https://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>]]></content:encoded>
    </item>
    <item>
      <title>HTTPS In 2015</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/https-in-2015</link>
      <pubDate>Fri, 16 Jan 2015 09:01:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2015/01/16/https-in-2015/</guid>
      <description><![CDATA[Last week at the CodeMash conference, I delivered a session titled HTTPS in 2015:

Securing your...]]></description>
      <content:encoded><![CDATA[<p>Last week at the CodeMash conference, I delivered a session titled <a href="https://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="https://ericlawrence.com/dl/Codemash2015-ericlaw-https-in-2015.pptx">here (pptx; 4.5mb)</a> and an audio recording of the presentation <a href="https://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="https://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="https://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="https://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="https://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>]]></content:encoded>
    </item>
    <item>
      <title>Script Polyglots</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/script-polyglots</link>
      <pubDate>Mon, 24 Nov 2014 13:25:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2014/11/24/script-polyglots/</guid>
      <description><![CDATA[Lately, there&rsquo;s been a resurgence of interest in hiding script inside files of other types;...]]></description>
      <content:encoded><![CDATA[<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="https://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="https://www.thinkfu.com/blog/gifjavascript-polyglots"><img style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/5148.image_thumb_52330119.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4405.image_1FCF2D9A.png" original-url="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/0753.image_5C86B62A.png" original-url="https://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>]]></content:encoded>
    </item>
    <item>
      <title>Compressing the Web</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/compressing-the-web</link>
      <pubDate>Tue, 21 Oct 2014 14:11:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2014/10/21/compressing-the-web/</guid>
      <description><![CDATA[Be succinct.
Virtually any network-based application can be made faster by optimizing the number of...]]></description>
      <content:encoded><![CDATA[<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="https://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="https://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="https://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="https://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="https://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="https://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="https://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="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3036.image_45185D80.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3652.image_thumb_023C1906.png" original-url="https://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="https://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="https://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="https://code.google.com/p/zopfli/">Zopfli</a>&nbsp;(pronounced "zopflee"); you can read more about it and its real-world savings over <a href="https://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="https://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="https://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="https://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="https://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="https://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="https://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="https://www.chromium.org/spdy/spdy-whitepaperhttps://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="https://en.wikipedia.org/wiki/Zip_bomb">Compression bombs</a>&rdquo;. The DEFLATE algorithm allows a peak compression ratio approaching <a href="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3005.image_763A28D1.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7242.image_thumb_05DCC494.png" original-url="https://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="https://tools.ietf.org/html/draft-alakuijala-brotli-01">Brotli</a>, yielding <a href="https://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="https://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="https://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>]]></content:encoded>
    </item>
    <item>
      <title>New Microsoft Message Analyzer Released</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/new-microsoft-message-analyzer-released</link>
      <pubDate>Tue, 16 Sep 2014 13:19:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2014/09/16/new-microsoft-message-analyzer-released/</guid>
      <description><![CDATA[If you want to monitor extremely low-level network traffic (e.g. TCP/IP packet flags, HTTPS alert...]]></description>
      <content:encoded><![CDATA[<p>If you want to monitor extremely low-level network traffic (e.g. TCP/IP packet flags, HTTPS alert records, etc), then <a href="https://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="https://blogs.technet.com/b/messageanalyzer/archive/2014/09/15/announcing-the-message-analyzer-1-1-release.aspx" href="https://blogs.technet.com/b/messageanalyzer/archive/2014/09/15/announcing-the-message-analyzer-1-1-release.aspx">https://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>]]></content:encoded>
    </item>
    <item>
      <title>Caveats for Authenticode Code Signing</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/caveats-for-authenticode-code-signing</link>
      <pubDate>Thu, 04 Sep 2014 12:14:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2014/09/04/caveats-for-authenticode-code-signing/</guid>
      <description><![CDATA[Back in 2011, I wrote a long post about Authenticode, Microsoft&rsquo;s Code Signing technology. In...]]></description>
      <content:encoded><![CDATA[<p>Back in 2011, I wrote a <a href="https://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="https://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="https://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="https://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="https://msdn.microsoft.com/en-us/gg463180.aspx">Windows Authenticode Portable Executable Signature Format</a> (and the less relevant <a href="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7178.image_0B1DFFAD.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/6445.image_thumb_210771FD.png" original-url="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/1754.image_459B9032.png" original-url="https://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="https://blog.didierstevens.com/2013/08/13/a-bit-more-than-a-signature/">blog post</a> describing this technique and offering a <a href="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7853.image_32E6967B.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3240.image6_209DCFB9.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/0045.image6_thumb_5BF13577.png" original-url="https://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="https://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="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/2211.image_16D86841.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/2630.image_3210C142.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3731.MD5_6644EA88.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4572.MD5_thumb_2AF4157B.png" original-url="https://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="https://en.wikipedia.org/wiki/Collision_attack">Collision Attack</a></li>
<li><a href="https://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="https://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="https://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>]]></content:encoded>
    </item>
    <item>
      <title>Optimizing Sprites</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/optimizing-sprites</link>
      <pubDate>Thu, 21 Aug 2014 10:09:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2014/08/21/optimizing-sprites/</guid>
      <description><![CDATA[Today, I&rsquo;m writing about a topic I personally know little about, but I&rsquo;ve heard experts...]]></description>
      <content:encoded><![CDATA[<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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3441.image_61138189.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3465.image_thumb_2319F0CB.png" original-url="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/2620.image_509B108E.png" original-url="https://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="https://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="https://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>]]></content:encoded>
    </item>
    <item>
      <title>Strict Transport Security</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/strict-transport-security</link>
      <pubDate>Mon, 18 Aug 2014 08:36:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2014/08/18/strict-transport-security/</guid>
      <description><![CDATA[Ivan Ristic&rsquo;s meticulously researched Bulletproof SSL &amp; TLS book spurred me to spend some...]]></description>
      <content:encoded><![CDATA[<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="https://status.modern.ie/?term=hsts">under development by the Internet Explorer team</a> and already <a href="https://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="https://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="https://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="https://tools.ietf.org/html/rfc6797#section-6.1.1"><strong>max-age</strong></a> value and optionally an <a href="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/3465.image_591A4AA2.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7510.image_2886CCEA.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/7026.image_24104C23.png" original-url="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/2248.image_75B6C675.png" original-url="https://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="https://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="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4747.IE11_5A80FE25.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/5344.IE11_thumb_6E2DE7B9.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/8446.chrome37_404325B2.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/4263.chrome37_thumb_1D81EDF5.png" original-url="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/5102.FF32_7AC0B637.png" original-url="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/8360.FF32_thumb_5C75FF41.png" original-url="https://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="https://tools.ietf.org/html/rfc6797#section-12.4">declined to require</a> safe <a href="https://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="https://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="https://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="https://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="https://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>]]></content:encoded>
    </item>
    <item>
      <title>URL Length Limits</title>
      <link>https://docs.microsoft.com/archive/blogs/ieinternals/url-length-limits</link>
      <pubDate>Wed, 13 Aug 2014 14:52:00 GMT</pubDate>
      <dc:creator><![CDATA[EricLaw [Edge]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/</guid>
      <description><![CDATA[Today&rsquo;s question is a simple one: &ldquo;What is the maximum URL length supported by Internet...]]></description>
      <content:encoded><![CDATA[<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="https://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="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/1104.image_36C5ECFD.png" original-url="https://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="https://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="https://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="https://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="https://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="https://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="https://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="https://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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/47/13/metablogapi/8816.image_638F89E8.png" original-url="https://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="https://msdn.microsoft.com/en-us/library/windows/desktop/bb787991(v=vs.85).aspx">EM_AUTOURLDETECT</a>) truncates the link after <a href="https://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>]]></content:encoded>
    </item>
  </channel>
</rss>