Thursday, April 5th, 2007
Protecting a JavaScript Service
There is increasing buzz over security with JavaScript, and people are stepping up to the plate.
In How to Protect a JSON or Javascript Service, Joe Walker looks at a few solutions such as:
- Use a Secret in the Request
- Force pre-eval() Processing
- Force POST requests
Joe implements some of these in DWR, including:
Prefix the script with throw new Error("message");. This is a neat solution in that it allows you to explain what is wrong to users that get the message by mistake.
Andrea Giammarchi wonders if 130 bytes are enough to solve JavaScript JSON Hijacking problems? in which he discusses tactics for detecting the hijacking of your objects and comes up with solutions such as this:
-
-
if((function(c,m,t){t=c[m];delete c[m];if(/^\[XMLHttpRequest\]$/.test(c)){c[m]=t;return 1}})(XMLHttpRequest,"toString"))
-
alert("Valid XMLHttpRequest");
-
else
-
alert("XMLHttpRequest is corrupted");
-
Finally, the GWT team has published an article on Security for GWT Applications that delves into how GWT handles JavaScript vulnerabilities such as leaking data, cross-site scripting, forging requests, JSON and XSRF.
A lot of good stuff.












Scott Guthrie posted to his blog yesterday about how ASP.NET AJAX handles this problem. It’s nice to see solutions for both JAVA and .NET.
http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx
Thank You Dion for this post but it seems that I didn’t find any solution.
JavaScript is “too much” dynamic (its a wonderful scripting language), You can redefine RegExp.prototype.test to return true when re is exactly “that”, you can define Function totally emulating normal behaviour, You can re-define in one private scope function Array, Object and Function itself.
I personally cracked (last update) every hacks to solve evaluation problem and as someone said in my first post about 130 bytes, there’s no way to solve problem using only JavaScript, we need, before them, to solve server-side security problems.
For example, wrapping JSON into comments is not a good practice if I can modify XMLHttpRequest object, as every other tips or trick You’ll apply only on client.
Simply make your code more secure starting from server-side and using best practices to do them.
This is only my personal opinion, Regards
KISS:
$headers = getallheaders();if(isset($headers['X-Requested-With']) &&
$headers['X-Requested-With'] == ‘XmlHttpRequest’) {
//…
}
Nathar, are You sure that a redefined XMLHttpRequest object cannot use setRequestHeader with that property?
Andrea, that doesn’t matter. Any attempt to use XMLHttpRequest (or any redefined variation thereof) is restricted by the same-origin policy which means it cannot access data from another domain. i.e., a site at http://www.angelfire.com/~hacker/ cannot access data from http://www.googlemail.com. If it uses a script tag, it cannot set any HTTP headers and so googlemail.com can block it. If it uses XMLHttpRequest, it can call setRequestHeader, but the request would be automatically denied by the browser because it is going to a different domain. Thus, Google can ensure that their JSON data is only accessible to sites hosted on http://www.googlemail.com.
What about just passing:
(function(){return {..json..};))
That’s simple, the json cannot be accessed without calling the lambda. Seems like the easy answer…
One gotcha to keep in mind is that if your server supports the Range header, someone could just use a byte range to fetch the inside of your JSON, rendering your comments and error throwing useless.