views:

360

answers:

4

I have http://example.com/index.html, which from within the HTML uses JavaScript (XmlHttpRequest) to call a web services at http://example.com/json/?a=...&b=...

The web service returns to index.html a JSON array of information to then be displayed on index.html.

Since anyone can view the source code for index.html and see how I'm calling the JSON web service (http://example.com/json/), how do I prevent people from calling my JSON web service directly?

Since the web service is essentially an open read into my database, I don't want people to abuse the web service and start fetching data directly from the web service, start DoS my server, fetching more information than they should, etc..

UPDATE:

Is there no way to limit requests for http://example.com/json/ to only come from the same server (IP) and URL request of http://example.com/index.html?

Meaning, can't http://example.com/json/ detect that the Requester is ($_SERVER['REQUEST_URI'] == http://example.com/index.html) and only allow that?

A: 

There are a wide array of things you can do to add security to your service. Check this out

Jason W
A: 

You can't properly secure a web-service that is callable from client-side javascript.

You can try security through obscurity techniques like javascript obfuscation, but it won't stop someone motivated.

rogeriopvl
+2  A: 

There are no easy way to prevent that. If your service isn't extremely popular and thus being likely target for denial of service attacks, I wouldn't bother.

One thing which came into my mind is using disposable tokens (valid for 10 or 100 requests).

Other (naive) approach is checking that X-Requested-With header exists in request, but of course that can be easily faked. So, my advice is: do nothing unless the problem is real.

One more idea: hash calc. The idea is to require client performing rather expensive calculation per every request, while validating the calculation in server side is cheap. For a single request the overhead is very small, but say for 1000 requests it may take significant amount of CPU time. I have no idea if hashcalc has been used to prevent DoS'ing web services. Some years ago it was proposed as antispam measure, but never became popular.

jholster
How would a disposable token work and be generated from an index.html file?
Hank
Well, the attacker could anyway re-fetch index.html to get new token, so neither is that very efficient countermeasure, unless you limit how many tokens are generated per minute per ip etc.
jholster
Related to HTTP_X_REQUESTED_WITH, I don't believe that's available in all languages ... e.g. PHP
Hank
In PHP you can access it via $_SERVER['HTTP_X_REQUESTED_WITH']. It won't stop real attackers, but prevents fetching the JSON by copy-pasting URL into browser's address field.
jholster
A: 

Answer is really simple, use CSRF protection. http://en.wikipedia.org/wiki/Cross-site_request_forgery

Simply, when user comes to your site (index.php), put in session: CSRF=(RANDOM_HASH)

Ask for JSON request, example.com/json.php?hash=$_SESSION['CSRF']

And in json.php check if $_GET['hash'] matches $_SESSION['CSRF']

Simple as that... It's Server-Side solution!

confiq
The idea is to prevent an attacker from accessing the services directly. Your approach won't solve that. The attacker will just access index.html, gets the token and thereafter makes the call to the service directly to get whatever information he wants.
sri
I assume this would be a one-time token. How can I do this without needing index.php, can I do this just with index.html?
Hank
File suffix doesn't matter, but CSRF requires "dynamic" pages, i.e. cannot be done with static files.
jholster
Of course it can't be done with static files and it's not ideal protection. However it will help restricting the server.As said before me, there are no easy way to prevent that...
confiq