Reputation: 649
So I have a main page that gets data from a JSON link and populates a dropdown based on that data. My question is, currently anyone can access the URL where the json is getting printed to and I want to secure it so that only the server and the pages running on the server can access the JSON output.
I was thinking of comparing PHP server vars such as remote_addr and server_addr but the remote_addr is the clients IP and not the server.
What is a good way to go about doing this?
Thanks
Upvotes: 1
Views: 6664
Reputation: 587
The security issue you refer to is known as JSON hijacking, and whilst some browsers now include features to mitigate the risk, it is still an issue in other browsers.
Fortunately there is a fairly simple solution. To understand it, we need to understand how the attack works in the first place.
It isn't actually possible for a third-party site to simply request your JSON file via an XMLHTTPRequest and parse it in the normal way, as this would be prevented by the same-origin policy.
So what the attacker does is redefine the object setter functions in JavaScript to return the values of any new objects to his own code, and then create a new <script>
tag referencing your JSON file. When the JSON is loaded the browser will execute it, create a new object, and return the values to the attacker's object setter handler. The attacker now has your data.
To prevent this, what you need to do is make it impossible to parse the JSON code directly as JavaScript. You want to make it throw an error if this is done.
One common way to achieve this (used by sites such as Google and Facebook) is to add code to the beginning of the JSON file which will create an infinite loop, preventing the parser from reaching the rest of the code (and throwing a JavaScript error).
For example, Facebook's JSON responses start with the string for(;;);
, while Google use various bits of code such as while(1);
, and throw(1); <don't be evil>
(the latter simply throws an error directly, rather than creating an infinite loop).
You will also then need to modify your own JSON handling JavaScript to strip this cruft out before parsing it. For example, you might do:
function parseJSON(json) {
json = json.replace("for(;;);", "");
/* parse your JSON as usual */
}
This adds a little bit of cruft to your script and your JSON, but is effective at preventing JSON hijacking.
Upvotes: 2