Reflected DOM XSS

Description

The website in this lab contains a reflected DOM vulnerability. Reflected DOM vulnerabilities occur when the server-side application processes data from a request and echoes the data in the response. A script on the page then processes the reflected data in an unsafe way, ultimately writing it to a dangerous sink.

Reproduction and proof of concept

  1. In Burp, go to the Proxy tool and turn Intercept on.

  2. Go to the target website and use the search bar to search for a random test string.

  3. In the Proxy tool forward the request.

  4. On the Intercept tab, notice that the string is reflected in a JSON response called search-results.

XSS

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 33

{"results":[],"searchTerm":"XSS"}
  1. From the Site Map, open the searchResults.js file and notice that the JSON response is used with an eval() function call.

function search(path) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            eval('var searchResultsObj = ' + this.responseText);
            displaySearchResults(searchResultsObj);
        }
    };
    ...
}
  1. Experiment with different search strings. The JSON response is escaping quotation marks. And backslash is not being escaped.

  2. Inject payload:

\"-alert(1)}//

When the JSON response attempts to escape the opening double-quotes character, it adds a second backslash. The resulting double-backslash causes the escaping to be effectively canceled out. This means that the double-quotes are processed unescaped, which closes the string that should contain the search term.

An arithmetic operator (in this case the subtraction operator) is then used to separate the expressions before the alert() function is called. Finally, a closing curly bracket and two forward slashes close the JSON object early and comment out what would have been the rest of the object. As a result, the response is generated:

{"searchTerm":"\\"-alert(1)}//", "results":[]}