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?
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.
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!
I would keep track of the IP addresses making the requests. If you ever saw a large number of requests coming from the same IP, you could block it or offer a CAPTCHA.
There are a wide array of things you can do to add security to your service. Check this out
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.