A few weeks ago I thought I’d stumbled across something really bad when just casually browsing the web. It all started on a financial information website, upon clicking a link, the page partially loaded some of its content, then, without warning, redirected the browser to a completely different domain with some weird spam/search engine content on it, from a known domain squatter.
After refreshing a few times, it was still doing it. Oddly, this behaviour seemed to only appear in Firefox; Chrome and Safari did not exhibit the same. This was a Firefox thing, I was sure of it!
After digging into the source of the affected website, it became apparent that something seemed off with this
<embed> tag for flash content:
They had hardcoded a URL to a SWF file on a domain since taken over by a squatter. A quick look on waybackmachine suggested the previous owner was a developer hosting some code they had written, but had since let the domain expire.
So instead, the browser gets whatever is now being served. This is bad in itself because they could craft a malicious SWF file to do nefarious things if they were really inclined.
However, even if they did return a SWF file, it didn’t explain why the redirect was occurring, because I don’t have Flash installed on my computer.
Flash or no flash
Setting top.location.href was causing the redirect to happen.
So wait a minute, the affected website had an
I raised this on bugzilla because at the time my initial thought was this was only affecting Firefox.
After writing a small application to mimic the issue, the browsers behaved differently when it came to setting the
- Chrome displayed a “click here to run flash” placeholder
- After enabling flash, it did not embed the response (i.e. it did nothing)
- Safari displayed a “Missing Plug-in” placeholder
After further investigation it turns out the “problem” can be replicated in Chrome too, using other MIME types like
type="video/webm". In this particular case the behaviour changed slightly
- Safari displayed a “Missing Plug-in” placeholder
I tried this with a few different MIME types and got differing results. You can see this in action on this demo page I built. Try it out on different browsers to see how they behave. Note if you have Flash or Quicktime installed, then you will see different results.
Embed ain’t so simple
One of the purposes of the
<embed> tag is to allow third party plug-ins such as Flash or Quicktime to be embedded into a page, but as these have fallen out of favour over the years it appears the general advice is “don’t use it”
Keep in mind that most modern browsers have deprecated and removed support for browser plug-ins, so relying upon 2
However, clearly the browsers seem to behave differently with the
type attribute, and how they handle the response. While Safari seems to be staunchly against doing anything without a plugin installed for the
type, Firefox and Chrome are a bit more of a mixed bag.
The firefox bug engendered some really interesting discussion, and their engineers implemented a patch to change this behaviour in Firefox, possibly scheduled for version 63! They also raised a spec bug on the HTML standards github around this to get some clarity on this issue. I thought that was really cool!
On the Chrome side of things, I filed a similar report, but they closed it, saying it was a larger problem with the web in general. Very polite and curt response, but fair enough.
You are correct that there can be a vector for crypto-miners, or possibly deceptive messaging to a user, but that is a larger problem on the web. When content is loaded there are signals as to what type of content it is, but we don’t constrain it based the the extension of the resource file (i.e. ‘.webm’).
As for the financial website? I eventually got a contact in their information security department and filed the issue with them. They’ve since fixed it by removing the hardcoded dependency on that domain and are hosting the SWF file themselves.
Is it a security bug?
I started out this journey just bumbling around on the web, and ended up encountering some behaviour that didn’t seem right.
But after thinking about it, I’m in two minds.
On the one hand, the
<embed> tag is doing its job, embedding stuff. The question is, if you specify the
type attribute with a valid MIME type, what should the browser do, and what should the fallback case be if the requested plugin cannot be handled or is missing?
You could argue that this is a non-issue that just stems from questionable coding practises, especially around hardcoding dependencies to third party sites that you cannot trust.3 However there is a bit of me that wonders if there are dark corners of websites out there that are embedding video4 or flash content from domains that have since changed owners, or started returning dodgy responses.
Clearly the domain squatter is setting
top.location.href for a reason, which makes me think they already know about this behaviour and are using it as a way to drive the browser into redirecting to their content. Other nefarious actors could use this ‘feature’ to silently embed cryptominers, or craft redirects to phishing websites, but it’s quite an involved process that relies on the ‘victims’ website embedding content from elsewhere, so probably not a high risk.
It was an interesting ride anyway.
UPDATE - 2018-08-13: The Chromium team kindly relaxed the viewing permissions on the bug I had filed (it was in their security space which is understandably restricted), so I’ve updated the post to include the link
- I didn’t have time to test Microsoft Edge, or Opera. It’s safe to assume Internet Explorer has weird behaviour though. [return]
- Quoted from MDN web docs - [return]
- Given the general advice for audio/video is to use the HTML5 media elements, this is probably a legacy issue. [return]