1

Is it possible to perform a cross-site scripting attack by entering my script into a field that is required to match a specific value?

I am scanning an application for vulnerabilities, and my scanning tool (OWASP ZAP) is returning several cross-site scripting vulnerabilities. The returned results include a path for a REST request, the associated method (GET or POST) and the parameter used to include the script.

The issue is that for each vulnerability, the parameter used is an id for a unique value. For example, a getUserPrivileges GET request is showing vulnerability using the parameter 'userId'. If I were to try to make this request in SoapUI, using an invalid userId, I would get a "Bad Request" response. There is also no place in the UI that would allow me to enter my own value for this parameter.

My assumption is that issues like these are all false positives, but, not being highly knowledgeable on this topic, I wanted to check my assumption.

If I am correct in this assumption, would there be any reason why such a false positive would come up? Is there something that would cause my scanning tool to mistake this for an issue?

Edit: Here are two example requests. One of them that I think may actually be a problem is Example 2. I notice that the "" text in that example is present in the raw response, but not in the html response.

(When I say that html content is not accepted, i am referring to the content in the request response. The settings for this are on the server-side. In Spring, this seems to appear with the absence of something like "produces=MediaType.TEXT_HTML_VALUE" in the method declaration and its substitution with something like "produces=MediaType.APPLICATION_JSON_VALUE".)

Example 1:

Request:
GET http://###.##.##.###:####/AAAAAAAA/BBBBBBBB/CCCCCCCC?    requestId=%3Cscript%3Ealert%281%29%3B%3C%2Fscript%3E&comments=%3Cscript%3Ealert%281%29%3B%3C%2Fscript%3E HTTP/1.1
Accept-Encoding: gzip,deflate
token: 2cd68a38-c3bd-a56b-e65c-b76da893cd4d

Response (Raw):
HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
token: 2cd68a38-c3bd-a56b-e65c-b76da893cd4d
token: 2cd68a38-c3bd-a56b-e65c-b76da893cd4d
Content-Type: application/json;charset=UTF-8
Content-Length: 167
Date: Wed, 22 Aug 2018 ##:##:## GMT
Connection: close

{"timestamp":#############,"status":400,"error":"Bad Request","exception":"java.lang.NumberFormatException","message":"For input string: '<script>alert(1);</script>'"}

Response (HTML):
unsupported content-type [application/json;charset=UTF-8]

Example 2:

Request:
GET http://###.##.#.###:####/AAAAAAAA/BBBBBBBB/CCCCCCCC?requestId=%3Cscript%3Ealert%28%22hello%22%29%3B%3C%2Fscript%3E HTTP/1.1
Accept-Encoding: gzip,deflate
token: 2cd68a38-c3bd-a56b-e65c-b76da893cd4d
Host: ###.##.#.###:####
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

Response (raw):
HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
token: 2cd68a38-c3bd-a56b-e65c-b76da893cd4d
token: 2cd68a38-c3bd-a56b-e65c-b76da893cd4d
Content-Type: text/html;charset=UTF-8
Content-Length: 173
Date: Wed, 22 Aug 2018 ##:##:## GMT
Connection: close

{"timestamp":#############,
"status":400,
"error":"BadRequest",
"exception":"java.lang.NumberFormatException",
"message":"For input string: '<script>alert('hello');</script>'"}

Response (HTML):
{"timestamp":#############,
"status":400,
"error":"Bad Request",
"exception":"java.lang.NumberFormatException",
"message":"For input string: ''"}
  • 1
    Sounds to me like the "Bad Request" response includes the id. Take a look at reflected xss. – AndrolGenhald Aug 20 '18 at 21:04
  • What do you mean by Response (HTML) There is only ever one response. How are you executing these requests? With your browser or some HTTP agent (e.g. curl, postman)? – Conor Mancone Aug 22 '18 at 13:50
  • These were generated by SoapUI, which allows me to switch between response content types. I imagine it simply interprets the content differently depending one which I choose. – harrys Aug 22 '18 at 14:17
4

As usual when using automated scanners, you'll need to do some manual testing to confirm this vulnerability or reject it as a false positive.

Why would ZAP label this as XSS?

From the ZAP documentation (thanks @SimonBennetts):

Cross Site Scripting (reflected)

This rule starts by submitting a 'safe' value and analyzing all of the locations in which this value occurs in the response (if any). It then performs a series of attacks specifically targeted at the location in which each of the instances occurs, including tag attributes, URL attributes, attributes in tags which support src attributes, html comments etc.

That means that ZAP's false-positive rate for reflected XSS is probably pretty low, ie most of what it reports is real, because it only reports things where the input is being reflected back in the page source in a way that appears vulnerable to one of the standard XSS mechanisms.

Anything it reports is worthy of further manual investigation.

What if there's no place in the UI to enter it?

Doesn't matter.

The most dangerous kinds of XSS are ones where the malicious payload is in a GET URL parameter, for example:

http://server/cgi-bin/testcgi.exe?usedid=<script>alert("Hello!")</script>

because then I can put that link into a phishing email and once you click on it, you're running my code!

So even though there's no UI element, ZAP has found some parameter in which it can inject code and the server will echo it back as part of the HTML page.

Do some manual testing

This is where you'll need to go inspect the page source / start playing with it until you've either produced an alert popup, or convinced yourself that the developers did proper output escaping.

To get you started, OWASP has a great XSS testing guide:

https://www.owasp.org/index.php/Testing_for_Cross_site_scripting

As @AndrolGenhald points out, the "Bad Request" page probably echos the input back to you without properly escaping it. If I hit your server with usedid=<script>alert("Hello!")</script>, I'm guessing it would serve me back an error page saying

Bad Request: "<script>alert("Hello!")</script>" is not a valid user.

If you look in the page source, I would hope you would see this properly escaped:

Bad Request: &quot;&lt;script&gt;alert(&quot;Hello!&quot;)&lt;/script&gt;&quot; is not a valid user.

which tells your browser to render this as text, rather than treating it as part of the HTML code. If it does not appear escaped in the page source, then with a bit of playing around you can probably get it to render as:

Bad Request: "

which means it actually ran the script rather than rendering it as text (and you'll probably have a nice popup to go with it). Hello reflected XSS attack vector!! (You just found a vulnerability, open a bug ticket and go have a beer)

  • LOL at first I put the examples in quote boxes rather than code boxes, and StackExchange helpfully removed the <script> and rendered the &quot. Not helpful!!! – Mike Ounsworth Aug 20 '18 at 21:55
  • 1
    For reference a summary of how ZAP tests for XSS can be found here: github.com/zaproxy/zap-core-help/wiki/… - ZAP does not just look for reflected values, it tries targeted attacks based on where the reflected values appear. That doesnt mean it cant produce false positives, but its generally pretty accurate so I would always investigate anything that it reports. – Simon Bennetts Aug 21 '18 at 7:47
  • Hmm. Something in this answer suggests that there is a problem, but I still cannot use it. With most instances, HTML is not an accepted content type. Would that be a sufficient protection? The one that is HTML returns "Bad Request" . . . "For input string: ''" (The quotes after 'For input string' have both the left and the right hand quotes.) – harrys Aug 21 '18 at 21:02
  • @harrys I'd have to actually see the full HTML message of the "Bad Request" to know, your description isn't enough. Also, can you expand on what you mean by "HTML is not an accepted content type"? You mean on the request or on the response? It's completely irrelevant what the content type of the request is, what matters is if the server is injecting user-supplied input into an HTML page. Go have a read of the OWASP link. – Mike Ounsworth Aug 21 '18 at 21:47
  • 1
    Thank you, Mike! This has become much clearer to me. I appreciate your willingness to help someone as poorly informed as myself. – harrys Aug 22 '18 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.