This Facebook bug could have allowed hackers to take over your account

A UK security researcher who goes by fin1te has just published the fascinating story of a Cross-Site Scripting (XSS) bug he found in Facebook’s content delivery network.

Fin1te (whose real name is Jack Whitton) reported the bug in July 2015, and apparently received $7500 for his efforts, but nevertheless waited until this week before going public.

He wrote that Facebook closed the hole with a few hours of his report, but he held off from disclosing the bug for six months to give Facebook time to implement a more complete fix.

XSS EXPLAINED

We’ve described XSS attacks before.

Very simply put, XSS refers to the sort of bug where you send a website content that deviously includes embedded JavaScript, and the website later (and incorrectly) includes that poisoned content in its reply.

For example, you’ve probably visited many websites that show your username at the top of every page once you’ve logged in.

That’s handy, as long as your name is something innocent like pducklin, and not something treacherous like <scr­ipt>ReadSomeCookie()</scr­ipt>.

If the website wrongly sends your browser a script in place of regular text or HTML, your browser will run it instead of simply displaying it, which amounts to a Remote Code Execution (RCE) attack.

Whenever a website displays or serves up any content that originally came from outside, whether buried inside an uploaded file or included in a URL, it needs to be very careful to filter out risky characters.

Dangerous characters notably include angle brackets (< and > signs), because they are used to denote parts of a webpage that should be treated as images, links, scripts and so on.

THR “CROSS-SITE” PART

Fin1te’s complete hack is quite involved.

Like many successful exploits, it requires a series of steps, or pivots, by means of which booby-trapped content uploaded in one place is then deviously made to show up somewhere else.

That’s the “cross-site” part of the attack.

Fin1te figured out how to upload hidden JavaScript to Facebook’s content delivery network (CDN), where files such as videos, images and so on get stored.

But CDN files typically get served up from a domain such as fbcdn.net or akamaihd.net, so even if you can sneak rogue scripts in there, when you load them back, they can’t read web data such as session cookies from facebook.com, because of a browser safety measure called the same-origin policy.

The same-origin policy stops me putting code on my website that retreives private web data set by your website, and is a key component of web security.

BYPASSING THE SAME-ORIGIN POLICY

Fin1te found a way to create a URL on the domain photos.facebook.com that was redirected to serve up his booby-trapped file from the CDN.

In short, he now had a way to upload a hidden script to the CDN, and then to retrieve that script via an innocent-looking link that a user could be tricked into clicking from a facebook.com domain.

His script would then run in the victim’s browser as if it were an official Facebook script.

If the user were logged in, the attack script could, at least in theory, do just about anything the user could do, including posting status messages and retrieving private data.

Of course, if I can surreptitiously send messages to your friends that include the same treacherous link to the script hidden on the CDN, then as soon as they read the messages, they’ll surreptitiously broadcast the script link to their friends, and so on, and so on.

An XSS attack that can be abused in this way is known as wormable, because it can be used to spread itself automatically across the network, making it a network worm or virus, much like the infamous Morris Worm of 1988, or Slammer from 2003.

THE NEAT PART

The really neat part of the vulnerability?

To upload the hidden script, Fin1te buried it inside the data part of a PNG-format image file so that Facebook’s CDN would recognise it as an image file, and thus incorrectly treat it as unexceptionable and therefore “mostly harmless.”

To do this, he needed to create well-formed image file that would load and display properly if treated as an image, but if processed in its raw form as plain HTML, would contain text such as <scr­ipt>DOBADSTUFF()</scr­ipt>.

But the data part of a PNG image is compressed with an algorithm called Deflate (the same compression as used in ZIP files), so Fin1te actually needed to find data that when used as input to Deflate, produced JavaScript as its compressed output.

Like a lot of security research, it’s only easy once you know how!