JSON responses can be exploited by overriding Array constructors or if hostile values are not JavaScript string-escaped.
Let's assume both of those vectors are addressed in the normal way. Google famously traps JSON response direct sourcing by prefixing all JSON with something like:
throw 1; < don't be evil' >
And then the rest of the JSON follows. So Dr. Evil cannot, using the sort of exploit discussed here. Get your cookie (assuming you're logged in) by putting the following on his site:
<script src="http://yourbank.com/accountStatus.json">
As for string escaping rules, well if we're using double quotes, we need to prefix each with a backslash and each backslash with another backslash etc.
But my question is, what if you're doing all of this?
Burp Suite (the automated security tool) detects embedded XSS attempts that are returned unHTML-escaped in a JSON response and it reports it as an XSS vulnerability. I have a report that my application contains vulnerabilities of this kind but I am not convinced. I've tried it and I can't make an exploit work.
So I don't think this is correct.
There is one specific case, that of IE MIME-type sniffing that I think could result in an exploit. After all, IE 7 still had the "feature" that script tags embedded in image comments were executed regardless of the Content-Type header. Let's also leave such clearly stupid behaviour aside at first.
Surely the JSON would be parsed by either the native JavaScript parser (Window.JSON in Firefox) or by an eval()
as per the old default jQuery behaviour. In neither case would the following expression result in the alert being executed:
{"myJSON": "legit", "someParam": "12345<script>alert(1)</script>"}
Am I right or am I wrong?
XSS occurs when a user-manipulatable value is displayed on a web page without escaping it, allowing someone to inject Javascript or HTML into the page. Calls to Hash#to_json can be used to trigger XSS.
Escaping from XSSEscaping is the primary means to avoid cross-site scripting attacks. When escaping, you are effectively telling the web browser that the data you are sending should be treated as data and should not be interpreted in any other way.
With JavaScript being extremely crucial to almost all modern web browsers, and automatically enabled almost universally, it might seem silly to want to disable it. However, for security sensitive environments, disabling JavaScript is a safe precaution to protect against malicious attacks such as cross-site scripting.
What is a JSON injection? The term JSON injection may be used to describe two primary types of security issues. Server-side JSON injection happens when data from an untrusted source is not sanitized by the server and written directly to a JSON stream.
This potential xss vulnerability can be avoided by using the correct Content-Type
. Based on RFC-4627 all JSON responses should use the application/json
type. The following code is not vulnerable to xss, go ahead test it:
<?php header('Content-type: application/json'); header("x-content-type-options: nosniff"); print $_GET['json']; ?>
The nosniff
header is used to disable content-sniffing on old versions of Internet Explorer. Another variant is as follows:
<?php header("Content-Type: application/json"); header("x-content-type-options: nosniff"); print('{"someKey":"<body onload=alert(\'alert(/ThisIsNotXSS/)\')>"}'); ?>
when the above code is viewed by a browser the user was prompted to download a JSON file, the JavaScript was not executed on modern versions of Chrome, FireFox and Internet Explorer. This would be an RFC violation.
If you use JavaScript to eval()
the JSON above or write the response to the page then it becomes DOM Based XSS. DOM based XSS is patched on the client by sanitizing the JSON before acting on this data.
Burpsuite (the automated security tool) detects embedded XSS attempts that are returned unHTML-escaped in a JSON response and it reports it as an XSS vulnerability.
Maybe it tries to prevent the vulnerability described in the rule 3.1 of OWASP XSS Cheat Sheet.
They give the following example of vulnerable code:
<script> var initData = <%= data.to_json %>; </script>
Even if double quotes, slashes and newlines are properly escaped, you can break out of JSON if it's embedded in HTML:
<script> var initData = {"foo":"</script><script>alert('XSS')</script>"}; </script>
jsFiddle.
to_json()
function can prevent this issue by prefixing each slash with a backslash. If JSON is used in HTML attribute, the whole JSON string must be HTML-escaped. If it's used in a href="javascript:"
attribute, it must be URL-escaped.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With