I have a JSON web service to return home markers to be displayed on my Google Map.
Essentially, http://example.com
calls the web service to find out the location of all map markers to display like so:
http://example.com/json/?zipcode=12345
And it returns a JSON string such as:
{"address": "321 Main St, Mountain View, CA, USA", ...}
So on my index.html
page, I take that JSON string and place the map markers.
However, what I don't want to have happen is people calling out to my JSON web service directly.
I only want http://example.com/index.html
to be able to call my http://example.com/json/
web service ... and not some random dude calling the /json/
directly.
Quesiton: how do I prevent direct calling/access to my http://example.com/json/
web service?
UPDATE:
To give more clarity, http://example.com/index.html
call http://example.com/json/?zipcode=12345
... and the JSON service
- returns semi-sensitive data,
- returns a JSON array,
- responds to GET requests,
- the browser making the request has JavaScript enabled
Again, what I don't want to have happen is people simply look at my index.html
source code and then call the JSON service directly.
You must duplicate all access control and business logic restrictions in the server as if none of it were present in your JavaScript client. Include the service in your SSO, restrict the URLs each user has access to, design the service keeping wget as the client in mind, not your well behaved JavaScript code.
You need data integrity protection. Digitally sign the json data using a hash algorithm (md5, sha-1, etc) and put the sign inside the json file. Next you need some sort of mechanism identyfing whether the data was forged or not.
In the case of JSON hijacking, the attacker aims to intercept JSON data sent to the web application from the web server. The attacker creates a malicious website and embeds a script tag in its code that attempts to access JSON data from the attacked web application.
JSON Web Services let you access portal service methods by exposing them as a JSON HTTP API. Service methods are made easily accessible using HTTP requests, both from JavaScript within the portal and from any JSON-speaking client.
There are a few good ways to authenticate clients.
Edit:
I didn't catch at first that your web service is being called by client-side code. It is literally NOT POSSIBLE to prevent people from calling your web service directly, if you let client-side Javascript do it. Someone could just read the source code.
Some more specific answers here, but I'd like to make the following general point:
Anything done over AJAX is being loaded by the user's browser. You could make a hacker's life hard if you wanted to, but, ultimately, there is no way of stopping me from getting data that you already freely make available to me. Any service that is publicly available is publicly available, plain and simple.
If you are using Apache you can set allow/deny on locations.
http://www.apachesecurity.net/
or here is a link to the apache docs on the Deny directive
http://httpd.apache.org/docs/2.0/mod/mod_access.html#deny
EDITS (responding to the new info).
The Deny directive also works with environment variables. You can restrict access based on browser string (not really secure, but discourages casual browsing) which would still allow XHR calls.
I would suggest the best way to accomplish this is to have a token of some kind that validates the request is a 'good' request. You can do that with a cookie, a session store of some kind, or a parameter (or some combination).
What I would suggest for something like this is to generate a unique url for the service that expires after a short period of time. You could do something like this pretty easily with Memcache. This strategy could also be used to obfuscate the service url (which would not provide any actual security, but would raise the bar for someone wanting to make direct calls).
Lastly, you could also use public key crypto to do this, but that would be very heavy. You would need to generate a new pub/priv key pair for each request and return the pubkey to the js client (here is a link to an implementation in javascript) http://www.cs.pitt.edu/~kirk/cs1501/notes/rsademo/
You can add a random number as a flag to determine whether the request are coming from the page just sent:
1) When generates index.html
, add a random number to the JSON request URL:
Old: http://example.com/json/?zipcode=12345
New: http://example.com/json/?zipcode=12345&f=234234234234234234
Add this number to the Session Context as well.
2) The client browser renders the index.html
and request JSON data by the new URL.
3) Your server gets the json request and checks the flag number with Session Context. If matched, response data. Otherwise, return an error message.
4) Clear Session Context by the end of response, or timeout triggered.
Accept only POST requests to the JSON-yielding URL. That won't prevent determined people from getting to it, but it will prevent casual browsing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With