1

Scenario : There is a persistent XSS on a page with the username information. The username is present three times in the page, is visible only once and the visible one is correctly escaped.

  1. How would you hide the payload so that it is not visible when the username is displayed ?

    • My first idea was to change the text displayed inside the payload.
    • Second idea using invisible characters :

    Bob">& nbsp;& nbsp;[...]PAYLOAD

  2. and if the payload cannot be executed on a specific page, how would you hide the payload ?

  3. How would you prevent your payload to execute more than once ?

    • Is it possible to use some kind of global javascript variable as a flag ?

2 Answers 2

3

To answer your three questions:

Fixing the properly escaped output:
Make your XSS patch the DOM so that the JavaScript you inject is removed from that particular tag. For example, you might prefix the injected XSS with a character such as a pipe (i.e. |) to help distinguish the real name:

var nameHtml = document.getElementById('username').innerHTML;
var parts = nameHtml.split("\">|", 2);
document.getElementById('username').innerHTML = parts[0];

So, if your XSS looks like this:

">|<script>alert(1);</script>

The code above will strip out everything after and including the ">|.

If you can't execute code on that page, can you do something else?
If you can still inject HTML into the page, but can't get the XSS due to a content security policy or something similar, then you could inject CSS to hide the username element entirely, using display: none !important; so that it overrides everything. If it's a stored XSS and you can CSRF the submit, then that would save you the hassle too.

How would you prevent your payload from executing more than once?
There are many ways to do this, including:

  • Check for the existence of an element with a known ID in the page - if it's found, don't run, otherwise create it.
  • Check for the existence of a named attribute on an element that you know exists in the target page - if it's found, don't run, otherwise add it.
  • Define a class or variable and check for its existence.
  • If you're trying to prevent it running again on refreshes, set a cookie.
0

You could use the XSS to change the visible username, so that it looks benign. For example, your injected script could do something like this:

document.getElementById("displayedUsername").innerHTML = "john";

To answer the second part of your question, yes you could ensure your code only runs once, using a global variable. The code would look something like this:

var alreadyExecuted;
if (alreadyExecuted !== true) {
  alreadyExecuted = true;
  // your code here

}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .