Note: We contacted Tesla (who have a bug bounty program) about this and the issue is now fixed.

Step one was to choose the target. He did Porsche… and we will do Tesla. A more hyped car company is hard to find, and after all, if you had to guess which car company has something to do with DOOM, Tesla would most likely be at the top of that list. Next up is the method. While buying a Tesla as marketing or research expense would be a lot of fun, we are not a car security company, but work with web security. There is also the distinct possibility our investors would not agree that a Tesla is a reasonable expense for a blog post. All things considered, hacking their website made much more sense.

Here comes the next problem – rumor has it that people do not appreciate it if you replace their website with a game just because you want to play. So it had to be fairly innocent, and at the same time have something to do with DOOM. See where this is heading?

The DOM DOOM XSS

We had to invent the DOM DOOM XSS. After some googling it seems like it has not been done before, but feel free to enlighten us. We gladly give credit where credit is due.

The technical aspect of this is pretty straightforward. We hosted a web version of DOOM at a domain we own (feel free to try it out) and went on to find a DOM XSS at Tesla. The DOM XSS was soon thereafter found at forums.tesla.com (it should be noted it is a self xss, meaning very limited potential impact).

We located the field under the Insert HTML button. That is what we were going to use. The function called when pressing that button is InsertHTML();

As value is the only parameter passed in editor.insertHtml(value) the mode will default to ‘html’ as per the documentation.

As can be understood by reading about ‘unfiltered_html’, ‘html’ implements a filter which we would have to bypass. We could now continue digging our way towards the holy game by clicking on the next link to CKEDITOR.filter. However, if there is anything the websec community should have learned by now it is that most filters are bypassable, so let us leave that part as an exercise for the reader.

To sum it up, after playing around with it we ended up with the following payload:

<img src="/" =_=" title="onerror='alert(document.domain)'">

And sure enough, the familiar little box telling us it worked was not far away:

We got a script replacing the whole page with an iFrame to the game hosted here, so now just a few lines of JavaScript to load in that script: