December 22, 2017

I've reported Stored XSS vulnerability and it was triaged, fixed, tested and deployed in less than an hour. On Friday. Before Christmas.

I like JavaScript. But in a different way than most people do. I like to put JavaScript code in unexpected places because it produces unexpected results. To be humble, after some time of doing this they are not that unexpected anymore. Remind me to tell you a story of how I named my SSH key and made it to the Atlassian Security Hall of Fame in 2014.

That's also why my site responds with some JavaScript in the Server header, because why have nginx when you can have <script/src=//xss.sk></script>, right? See, I even had Server-side JavaScript before it was cool.

server: <script/src=//xss.sk></script>

The thing is that some tools like to show you the contents of the header, to tell you what server the site is using. That's also the case of Whois listing at DomainTools, the service I've been using quite often, not only because I can remember the shortcut: whois.sc/<domainname> (Whois Source) but also because it offers links to other rather useful tools like reverse lookups etc.

Today I've finally got this great idea to see how the whois record looks like for my domain. Just slightly unexpectedly I was greeted by this familiar JavaScript alert:

💩 JavaScript is bad, m'kay?

Can't disagree, so I click OK and I hear Mr. Mackey's voice explaining that drugs are bad (because drugs are bad) and I'm like aha, that's what my JavaScript on xss.sk does! DomainTools didn't properly escape my Server header and my browser has executed the JavaScript served by xss.sk, it displays an alert and embeds this South Park video. There's some Accept header parsing involved so you won't see the code when you visit the site directly in your browser.

I've pinged my friend Scott Helme, whom I've been working with on Report-URI, because I remembered he once said he knew somebody in DomainTools. Scott has promised to let them know, and in less than an hour, DomainTools have triaged and fixed the bug, and tested and deployed the patch to production. It's Friday, before Christmas. Hats off, guys, hats off. Now this is how you respond to a disclosure! Alerts and funny videos are one thing, but with JavaScript running in the context of the page you can steal cookies, tokens, create fake login forms or do anything else with the page, if no other restrictions (like HTTPOnly cookie flags or Content Security Policy) are in place.

The listing looks like this after the fix:

Server Type <script/src=//xss.sk></script>

If you're wondering about the slash between script and src, that's because some sites have replaced the space with &nbsp; when displaying the header, and browsers didn't recognize the tag. Slash prevents that, but it still allows browsers to recognize the script tag and the src attribute correctly.

Here's a really short timeline but I just have to include it because the intervals are awesomely short (times are in CET, UTC +1):

  • 16:20 I ping Scott, provide the link to the vulnerable Whois listing, ask him to let DomainTools know
  • 16:27 Scott sends an email to DomainTools
  • 16:34 Scott gets a response from DomainTools, they are escalating
  • 16:45 Scott gets an email from DomainTools CTO with a confirmation they're patching
  • 17:09 Scott says it should be fixed

The fix was probably quite simple but still, in less than an hour from my initial report to Scott, and 42 minutes from Scott's email to DomainTools, left me speechless. That was a nice experience, thanks DomainTools for a quick response and thanks Scott for being a messenger.

Now ask yourself, how long is your response time to issues like this one, hmm?

Michal Špaček

I build web applications and I'm into web application security. I like to speak about secure development. My mission is to teach web developers how to build secure and fast web applications and why.

Public trainings

Come to my public trainings, everybody's welcome:

PHP application security
(December 11–12, 2018 Praha)

HTTPS for developers and admins
(December 13, 2018 Praha)