Reputation: 15559
I came across the following ASP.NET MVC error, when returning json
in a Get
method:
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
Apparently this vulnerability is called json Hijacking. This article explains that a website could be exploited when returning json
using Get
. But returning json
in a Post
method is safe.
Why changing Get
to Post
prevents this attack?
Upvotes: 9
Views: 5911
Reputation: 11622
Having the request as a POST
will prevent any request coming form other domains based on CORS policy unless you configure your server to allow it, which turns this issue to another thing. GET
requests on the other hand are allowed by browsers to retrieve resources, like javascript that might have sensitive data from your domain and it happen to be an array not an object.
Updated answer:
You will not actually find a source tells you how GET
, POST
requests are different for JSON Hijacking
attacks. The difference actually is how web servers and browsers are dealing with those requests. JSON hijacking vulnerability is about malicious websites using an endpoint in your website/app that provides JSON data and response to a GET
request (a request that by default allow resources, e.g js, images, text files to be download), if you change it to POST
, they will not be able to include <script>
that do a POST
request from the src
attribute, even inside the script tag POST
requests will be prevented by CORS policy.
In the modern browser era we no longer have this type of vulnerability (at least in the form mentioned in the discovery article by Jeremiah Grossman) because of CORS policy.
This also referenced in other related questions
Upvotes: 4
Reputation: 2337
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 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.
Upvotes: 8
Reputation: 1916
If you open the network panel on any webpage that contains scripts, images, stylesheets or fonts you will see that all those requests are done using GET
HTTP method. For example this is how a request for a file loaded by a <script>
tag looks like:
And this is an example for an file loaded by an <img>
tag looks like:
Browser will just blindly trust you that if you are loading such a resource from anywhere you know what you are doing and it will fetch it for you (otherwise things like CDN would not work) as opposed to an XHR request!
XHR requests (including fetch
calls) are checked against CORS policy, I believe you are familiar with what that is. JavaScript will not be able to make any XHR request for a resource that lives on a different domain (or port etc.).
So you have two types of request policies:
img
, script
, link
etc will not be checked against CORS policy but you are restricted to GET
HTTP requests only. The browser will also send all the cookies along, most importantly the authentication ones in this case.That means that if you are serving a JSON array using GET
you can use a script
tag to fetch it for you no matter which domain you are on. Then, using the trick mentioned in the article, you can execute the array (sounds weird but yes) and grab the sensitive information.
If you'd be using POST
, the attacker has no way of using a script
(or any other) tag to perform this request since they use GET
requests to fetch resources.
You could think Ah but I can use form
to do that! but you will run into the same CORS issues. If you just submit a form
, the JSON data will load into the current page and there is no way for you as an attacker to get it since your script no longer exists on the page.
You could think Ah I just set the form
target to an iframe
! but JavaScript will not allow you to access anything within that iframe
.
Does that make sense?
Upvotes: 2
Reputation: 835
JSON shouldn't be returned as GET
because the data can be stolen with an injected <script>
from an attacker (for example, if dynamic content is loaded without being HTML escaped). Scripts are requested from the server via the GET
method, so anything sent from the server with POST
won't be ran from an injected script. With their script being ran, the hacker can use your logged in cookie to access your JSON, which they shouldn't be allowed to get.
Read more about JSON hacking vulnerabilities in this article and this SO answer.
Upvotes: 1