Sunday, August 12, 2018

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.

Strange…

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:

< embed id = "button" src = "http://<squatters-domain>/zclip/js/ZeroClipboard.swf" type = "application/x-shockwave-flash" > </ embed > Always host your own

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

This is where I begun to think this was a security issue, because the response for the ‘swf’ request was HTML with some javascript in it, with the smoking gun being right here:

if (top.location != location){ top.location.href = location.protocol + "//" + location.host + location.pathname; } Get the browser to it!

Setting top.location.href was causing the redirect to happen.

So wait a minute, the affected website had an <embed> tag in it, expecting some flash content, but got served some HTML+Javascript instead, which it embedded and executed? That seemed weird fallback behaviour to me.

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 type to application/x-shockwave-flash

Chrome displayed a “click here to run flash” placeholder After enabling flash, it did not embed the response (i.e. it did nothing)

Firefox embedded the response so executed the javascript

Safari displayed a “Missing Plug-in” placeholder

Examples of the placeholders in Safari/Chrome

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

Chrome embedded the response so executed the javascript

Firefox embedded the response so executed the javascript

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 is generally not wise if you want your site to be operable on the average user’s browser

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.

Results

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. However there is a bit of me that wonders if there are dark corners of websites out there that are embedding video 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.