True Stories of the TRC-Web Application Security

Anatomy of an XSS Injection

I love XSS, especially in JavaScript space. It’s like a puzzle. Sometimes it’s a four-piece jumbo jigsaw puzzle, like landing in an empty script tag with no filtering or encoding, but other times it’s a 10,000-piece mystery, requiring a complex injection to overcome multiple obstacles. Either way, it’s always satisfying when that ‘1’, ‘xss’, or ‘lol’ pops up in an alert window.

Break Out, Execute Payload, Blend In

There are typically three pieces to an XSS injection: break out, execute payload, and blend in.  Consider the following:

Injection:  xss

Reflection:

<script>x="xss";y=42;</script>

In order to execute payload, we have to break out of the double-quoted string we’re landing in.

Injection (break out):  xss";

Reflection:

<script>x="xss";";y=42;</script>

We’ve now broken out and terminated the x= line of code; it’s time to inject some payload.

Injection (break out + execute payload):  xss";alert(1);

Reflection:

<script>x="xss";alert(1);";y=42;</script>

Our payload is in place, but the "; following our injection is not proper syntax and will cause an error; we need to blend back in to the remaining code.

Injection (break out + execute payload + blend in):  xss";alert(1);//

Reflection:

<script>x="xss";alert(1);//";y=42;</script>

By adding a comment, our injection now results in syntactically correct code that will execute our payload successfully.

Sometimes there’s nothing to break out of or blend back into, but often both are necessary in some degree to ensure that the code is syntactically valid and that the payload is executable.

Complex Breakouts

Sometimes the code path doesn’t allow your injection to fire, like when landing inside a function that’s never called on the page. In those instances, assuming that you can’t use </script> to break out, you must break out of any strings you’re in, as well as the actual function.  Furthermore, the end of your injection must blend back in to whatever code follows:

Injection:  xss

Reflection:

function neverCalledOnThePage()

{

x="xss";

}

Injection:  xss"}alert(1);if(0){//

Reflection:

function neverCalledOnThePage()

{

x="xss"}alert(1);if(0){//";

}

Helpful tips for dealing with this type of scenario are highly dependent on context, so I won’t go into any more detail here. Basically, break out from as little as is needed in order to get into executed space, and be as minimalistic as possible when blending back in to the code (use a comment, if possible). Replicating exactly what was present before you broke out is usually not necessary; however, referencing what was present is useful when crafting a syntactically correct blend back in to the code.

Tags: Cross Site Scripting, JavaScript, XSS
  • http://www.websafe.ie james ford

    Your example while it is simplistic is perfect to explain it, I might use the same code for a similar blog on http://blog.websafe.ie if that would be acceptable

    • http://www.justinbarron.com/ Justin Barron

      James, I apologize for the delay in replying, but you are more than welcome to use the same code for your blog. Let me know when the post goes up; I’d love to check it out!

  • “>