I recently discovered an XSS vulnerability on a website I occasionally use. They let you edit your biography using a WSYWIG editor, which also means you can edit the raw HTML of the biography. As I was fiddling with it, I noticed that they didn’t allow inline event listeners such as onerror
. That meant that this code:
<img src="https://fake" onerror="alert('XSS');">
got converted to
<img src="https://fake" eventsnotallowed="alert('XSS');">
It’s good that they block JavaScript that way. But did they also strip mixed-case event attributes from tags? Turns out they didn’t. So by randomly capitalizing onerror
, I was able to run any JavaScript code of my choosing1 on the website by using something like this:
<img src="https://fake" oNeRRoR="alert('XSS');">
It felt good to find an XSS vulnerability, submit it to them, and see it be fixed. As an added bonus, I was granted a year of premium membership on the site.
-
The WSYWIG editor would try to clean up anything it thought was invalid HTML. So,
oNeRRoR="document.innerHTML += '<script src=\'...\'></script>';"
resulted in random jumbled HTML. Of course, usinginnerHTML
isn’t necessary to put a tag at the end of the page, it just makes it slightly easier. ↩