The more time that goes by and the more deeply I give it thought, the more convinced I am that the web is held together with sticky tape. No - cyber-sticky tape! Because especially when it comes to security, there are fundamental and inherent shortcomings in everything from HTTP to HTML and many of the other acronyms that make the web work as it does today. We've been trying to get this right for 25 years as of yesterday too:
Today: The 25th anniversary of the web: https://t.co/57NuBcpuqt
— Mikko Hypponen (@mikko) April 30, 2018
Thanks CERN and Sir Tim Berners-Lee! #madeineurope
Cross site request forgery is a perfect example; here we have a situation where the browser will happily send cookies along with requests (including auth cookies) thus issuing said request under the identity of the logged in user. Click a malicious link from an attacker which causes a carefully constructed request to post data of their choosing and things can work out rather unpleasantly. So we developed anti-forgery tokens to address this. We didn't fix the underlying issue because that's fraught with all sorts of other problems, we just sticky-taped over it. (And yes, "same-site" cookies will fix this but as of today, only Chrome supports it.)
And so it is with trusting JavaScript served from third parties. I recently wrote about the Browsealoud problem where a cryptominer ended up on a bunch of government websites due to them embedding an external script and allowing it to run whatever it wanted to in the context of their site. In that post, I talked about the benefits of subresource integrity or as we often know it, SRI. But like same-site cookies, it only works in browsers that support it which, until today, meant no support in Microsoft Edge. But as of Edge 17 which just shipped with the April Windows 10 update, that's all changed:
Naturally I wanted to see this in action so I created a little test page and gave Edge a go before updating my machine. Pre-test, it was sitting on version 16:
Which resulted in the following on the test page:
This is implemented by embedding the script tag as follows:
<script src="/js/SRI-test.js" integrity="sha256-invalidHash" crossorigin="anonymous"></script>
The integrity attribute doesn't contain a valid hash therefore any browser that supports SRI shouldn't execute the JS (which just pops up an alert box). I jumped into Windows Update, took the new bits and tested the version again:
So the update is good, let's look at what that now means for the test:
Success! Edge now joins the other major browsers in rejecting any script which doesn't hash down to the value specified in the integrity tag. This should give a boost to anyone considering SRI but reluctant to serve their content from external locations (such as a faster public CDN), due to concerns around incidents like Browsealoud. This has been a long time coming. That UserVoice idea goes back to August 2014, Chrome started supporting SRI in September 2015 and Firefox followed a few months later in December.
Another feature that's been missing from Edge and arrives in this update is Upgrade-Insecure-Requests. I talk about this in detail in my 6-step happy path to HTTPS so I'll give you just a quick recap here. Take this test page loaded in Edge 16:
This is not a happy web page because whilst it's been loaded over HTTPS, the logo has been embedded over HTTP so we have mixed content. The image still loads because it's passive content and it can't actually do anything (try this exammple with JavaScript which is "active" content and will refuse to load), but the padlock icon is now gone and obviously there's also an error in the console. Not only is there an error, but there are a couple of warnings about Edge 16 having no idea what Upgrade-Insecure-Requests is and consequently deeming the content security policy to be empty. In Edge 17, however, things are much nicer:
So this is great because these are two of my favourite native browser security controls, but why the wait? I don't want that question to go unaddressed here because inevitably, some of the first feedback I'll get from people about this blog post will be the lead time it took. And before anyone starts, no, I don't work for Microsoft but I do have strong opinions I voice to them on a regular basis!
Let's start with the Edge platform status:
That's 107 things sitting somewhere being considered and not yet live. When the Edge folks sit down and plan what to build next, they're tossing up between the vibration API that's under consideration, investing resources into ongoing development of the same-site cookie support I mentioned before and getting support of the meta referrer attribute wrapped up. In short - prioritisation. Now consider a feature like Upgrade-Insecure-Requests in the content of Scott Helme's Alexa Top 1 Million analysis from Feb:
We've got less than 2.5% of the world's biggest websites using a CSP, therefore a subset of that are using the directive within there to upgrade requests. When the numbers are that small, you can see how it slips down the list of 100+ other features on the request roadmap.
Now, having said all that, I would have liked to have seen this much earlier and certainly I've pushed for it. The best possible way that we as a community of developers and security people can bump features like these and all the others to come up the priority list is to use them in more websites! Want to see CSP level 3 supported in Edge - use it! It's a chicken and egg game, of course, because people are reluctant to lean on features with limited support, but you can go out and add things like same-site cookie support with little effort and do the anti-forgery token dance at the same time. Make it as compelling as possible for the browser vendors - all of them - to want to use these features.
For now, I'm just happy to see this support come in Edge because it means that when I'm running workshops or writing blog posts or speaking, I can now say "SRI and Upgrade-Insecure-Requests are supported across all the major browsers - just do it!"