5

I am testing a scenario with Burp proxy.

  1. I am located on a website https://website.com/web

  2. There's an option there to delete an item, when you click it , a certain POST request is sent (XMLHttpRequest, no page refresh is happening) where I can insert a <script> tag:

    POST /web/deleteItem HTTP/1.1
    Host: website.com
    
    returnParameter=<script>alert('xss')</script>
    
  3. deleteItem method returns the following:

    HTTP/1.1 200 OK
    Date: Tue, 31 Jan 2017 22:18:54 GMT
    X-XSS-Protection: 1; mode=block
    Content-Type: application/json;charset=UTF-8
    ...
    
    {"status":"SUCCESS","result":"<script>alert('xss')</script>"}
    
  4. On a website from step #1 there are JavaScript functions that parse the JSON and show its result value on the screen

  5. alert is being shown on https://website.com/web, so reflected XSS was successfully executed.

But this scenario is not realistic as I need to draw a user to the website and execute the XSS somehow.

I have tried this by making a simple HTML POST form and submitting the parameters to https://website.com/web/deleteItem. Lets say that I would use phishing and user would submit the form.

The action was indeed executed, but I only received a JSON response. There was no page from step #1, so nothing was actually shown as XSS, because the user was not located on https://website.com/web where alert('XSS') should be executed. I am not sure is it possible to send the user to page #1 and send it this JSON with XSS somehow.

Could there be a way to execute this scenario in realistic conditions?

2
  • In step two, how do you insert the script tag into the POST request?
    – Anders
    Feb 1, 2017 at 12:08
  • @Anders populate the form with whatever values you want, then submit the form with javascript: form.submit()
    – rook
    Feb 2, 2017 at 4:53

1 Answer 1

5

The proposed reflective XSS vulnerability is completely and totally unexploitable by modern browsers due to the following content-type:

Content-Type: application/json;charset=UTF-8

The content-type needs to be HTML, or a missing content type would do the trick. Having a content-type application/json or plain/text are both strong mitigations against XSS.

Content sniffing can be used by old browsers to execute JavaScript despite the defined content-type. As an attacker, if the target browser still uses content sniffing, then the browser is also vulnerable to worse bugs, like drive-by remote code execution.

As @Jeroen pointed out, this is an insecure input validation issue, and although it might not be vulnerable to reflective XSS, it could lead to other problems such as 2nd order code injections, and persistent XSS.

4
  • 1
    Although this is 100% correct (+1), it is still lacking input validation and I recommend reporting it as such if this is a penetration test. Developers should learn to validate all their input at all times regardless of the content type. I have seen scenario's where JSON data is stored in a database and another application reads that data and the payload gets executed anyway (due to the lack of output encoding)
    – Jeroen
    Feb 1, 2017 at 5:23
  • While you have a point about json, I wouldn't be so careless to dismiss plain/text as solved for over 10 years and I certainly wouldn't call it a strong mitigation. IE8 is afaik vulnerable, which was supported until 5 years ago and which is the last IE version working on windows XP. While not supported anymore, XP is still used in praxis more often than we would like.
    – tim
    Feb 1, 2017 at 20:54
  • @Jeroen - IT Nerdbox updated.
    – rook
    Feb 2, 2017 at 4:48
  • 2
    @tim if you haven't updated your browser in 5 years, or even 5 months, you'll get hacked by a drive-by exploit. Anyone still running IE8 has bigger problems on their hands than reflective XSS.
    – rook
    Feb 2, 2017 at 4:50

You must log in to answer this question.

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