Is JSON Hijacking Still an Issue in Modern Browsers

Is JSON Hijacking still an issue in modern browsers?

No, it is no longer possible to capture values passed to the [] or {} constructors in Firefox 21, Chrome 27, or IE 10. Here's a little test page, based on the main attacks described in http://www.thespanner.co.uk/2011/05/30/json-hijacking/:

(http://jsfiddle.net/ph3Uv/2/)

var capture = function() {    var ta = document.querySelector('textarea') ta.innerHTML = ''; ta.appendChild(document.createTextNode("Captured: "+JSON.stringify(arguments))); return arguments;}var original = Array;
var toggle = document.body.querySelector('input[type="checkbox"]');var toggleCapture = function() { var isOn = toggle.checked; window.Array = isOn ? capture : original; if (isOn) { Object.defineProperty(Object.prototype, 'foo', {set: capture}); } else { delete Object.prototype.foo; }};toggle.addEventListener('click', toggleCapture);toggleCapture();
[].forEach.call(document.body.querySelectorAll('input[type="button"]'), function(el) { el.addEventListener('click', function() { document.querySelector('textarea').innerHTML = 'Safe.'; eval(this.value); });});
<div><label><input type="checkbox" checked="checked"> Capture</label></div><div><input type="button" value="[1, 2]" /> <input type="button" value="Array(1, 2);" /> <input type="button" value="{foo: 'bar'}" /> <input type="button" value="({}).foo = 'bar';" /></div><div><textarea></textarea></div>

Why json hijacking can be prevented using POST method?

I was really surprised to see that so many people is trying to prove that JSON Hijacking is still a security issue. (Of course it is if you still use Firefox 2, Opera 9, or Safari 3). None of the modern browsers have this issue for a long time. The article you referred in your question is written in 2009. You can check this post for more information about how the issue was fixed. And you do not need to worry about JsonRequestBehavior just allow get and forget.

UPDATE

Sorry, I have not read the bounty question. Why changing request to post prevents json hijacking?

You can find a article here, that describes the JSON Hijacking attack steps. It goes as follow:

  • Step 1: Get an authenticated user to visit a malicious page.
  • Step 2: The malicious page will try and access sensitive data from the application that the user is logged into.This can be done by embedding a script tag in an HTML page since the same-origin policy does not apply to script tags.

    <script src="http://<jsonsite>/json_server.php"></script>

    The browser will make a GET request to json_server.php and any authentication cookies of the user will be sent along with the request.

    ...

You can think this scenario like that, user visits www.yoursite.com and get authenticated. After that user leaved your site and go to a malicious site. If the malicious site has a <script src="http://www.yoursite.com/some_endpoint"></script> tag, browser will make a GET request. If returned data is a JSON that site can get the sensitive data by object prototype setter. (Remember attackers will try to use SCRIPT tag not an AJAX request because same-origin policy does not apply to script tags. See Cross-origin network access rules.)

But if you change the request type of the http://www.yoursite.com/some_endpoint from GET to POST, when the browser tries to access it, your server will reject it.

Also i am leaving a old MVC Framework book here that explains concept.

Is it possible to do 'JSON hijacking' on modern browser?

It's not about the legitimate application parsing the JSON - JSON hijacking is an information disclosure issue about some malicious party requesting your JSON data instead of the real application while the user is logged into the application that uses the api usually. Simple authentication does not help - as the browser sends the auth information e.g. auth-cookie for free :-/.

But with ES5 most current browser won't be affected anymore directly by this issue. Nonetheless, in depth defense rules! And may protect against future issues too or regressions and etc.

Difference between )]}',\n and {} && in avoiding json hijacking

Anything that stops the JSON response being parsed as a JavaScript object or array will prevent this method of JSON Hijacking.

See this post for some methods of making your JSON secure.

However, as this answer states, it is not really an issue since Firefox 3.

Google uses an "unparseable [cruft]" to defend its self against this type of attack. It should be noted that this vulnerability has been fixed in firefox 3, and this vulnerability arises from how browsers impalement the json specification.

At the time of writing Google appear to prepend )]}' to their responses from Gmail.

Why does Google prepend while(1); to their JSON responses?

It prevents JSON hijacking, a major JSON security issue that is formally fixed in all major browsers since 2011 with ECMAScript 5.

Contrived example: say Google has a URL like mail.google.com/json?action=inbox which returns the first 50 messages of your inbox in JSON format. Evil websites on other domains can't make AJAX requests to get this data due to the same-origin policy, but they can include the URL via a <script> tag. The URL is visited with your cookies, and by overriding the global array constructor or accessor methods they can have a method called whenever an object (array or hash) attribute is set, allowing them to read the JSON content.

The while(1); or &&&BLAH&&& prevents this: an AJAX request at mail.google.com will have full access to the text content, and can strip it away. But a <script> tag insertion blindly executes the JavaScript without any processing, resulting in either an infinite loop or a syntax error.

This does not address the issue of cross-site request forgery.

CSRF prevention for GET requests

An attacker could include the following script on their page:

$.get('http://vulnerable.example.com/json')

However, due to the Same Origin Policy, the JavaScript on the attacker's domain couldn't read the response. The same origin policy checks whether the domain, protocol and port match - if they don't the JavaScript will encounter a security error when trying to read the response. For example, this is the warning Chrome gives when trying to access an IFrame from another domain - this is exactly the same mechanism that will protect the JavaScript response.

Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': blocked a frame with origin "http://evil.com" from accessing a frame with origin "http://vulnerable.example.com". Protocols, domains, and ports must match.

So in summary, POST requests must use a CSRF token as the POST request will still be made even though the response cannot be read and GET requests are not normally a cause for concern as the response cannot be read and they are non destructive. There was the issue with JSON Hijacking, but you have to go back as far as Firefox 3 to find a browser vulnerable to this. See Is JSON Hijacking still an issue in modern browsers?



Related Topics



Leave a reply



Submit