We have a webpage that we provide to partner companies via an iFrame. The iFrame contains several javascript files that make ajax requests to our server for data. The iFrame itself requires an API Key that is keyed to the domain of the partner. This prevents the iFrame from displaying if it is installed on a domain that isn't registered. However, it would be pretty easy to simply copy the contents and javascript files of the iFrame from a registered site and host them on a non-registered site.
Ideally we'd like to use the API key to restrict Ajax requests and prevent our server from providing the requested data for non-registered sites. However, it appears that the HTTP_REFERER server variable is not set for Ajax requests. How can we tell what site that the request is coming from? Is it possible? If not, how can we prevent unauthorized access?
Relying on HTTP_REFERER isn't the way to go. You want your client's website to use an API to contact your website over a secure link, and get a temporary session string, which is then used as part of the source url for the IFRAME, which is how google does it (not with referer.)
Make the url for the IFRAME valid for a limited time, after which you display a nice message about going back to the client's page to start over.
When the iframe is requested you can generate a unique ID on your server, then set that as a cookie on the client. Every AJAX request should contain that cookie. Only keep around the ID's for the last hour or so.
You can never rely on HTTP_REFERER because some proxy servers and firewalls will strip it out to preserve users' privacy.
The challenge is that the iframe is authorized to a specific domain, so my API Key is tied to that. I followed the following tutorial to generate my API keys.
https://ajax.dev.java.net/ajax/api-keys
Do you think that relying on the HTTP_REFERER variable will prevent users from accessing the iframe? Sun claims that Google uses this method for Google Maps API authentication.
Once the API key has been authenticated, then the cookie approach should do the trick, I think. Thanks!
Related
I know CURL & HTTP authentication to allow API calls only from certain requests.
I have something like this
www.mysite.com/list
www.mysite.com/api
list page calls the api page using jQuery Ajax post request and api page echos jSON response.
I am already checking HTTP referrer to verify Post requests come from certain origins but these requests can be forged.
I cannot use $_SERVER['remote_addr'] as this will check the client ip not the source ip of the API request.
As both the pages are hosted in the same web server and in the same hostname, its not possible to restrict based on hostname or IP address.
I am aware of some alternatives like
cURL with HTTP Authentication.
Encryption of jSON response and Decrypting before printing.
But is there any way to restrict these API pages to securely block access from outside the server or hostname?
Assuming you want to restrict access to "Joe Random user who is visiting your website with a web browser".
Not really.
There's no way to reliably determine that the client is a regular web browser. Anyone writing some other client to access your API can easily have it visit your website and get whatever tokens they need to prove that.
The best you can do is some sort of heuristic approach that looks for unusual traffic patterns (such as unusually high numbers of similar requests from one source, or ones which have very stable intervals between requests). You'll get false positives and negatives from that kind of approach though.
I may be wrong, but I think you are trying to invent csrf tokens. But with little modification:
You should store generated token in session/cookie before rendering /list. I am not sure whether jQuery send session/cookie with ajax request by default, but I think it should not be a big problem if not, to append it.
When you will process /api request you should validate cookie/session also for the token existance.
I have a jQuery script in a clientDomain.com/show.php page that shows some data loaded from a serverDomain.com/echo.php page using jQuery.getJSON(). I want that only allowed domains can show the data because I don't want that unauthorized people install the script in their own website without my permission. Is there any way to restrict the response of a jQuery.getJSON() only to certain domains? The solution should prevent also the use of iframe by the client. In conclusion, the data should be seen only if someone visit directly serverDomain.com/echo.php page or one of the allowed client domains. Thanks in advance for the support!
My request/response script works like the first example in jQuery.getJSON() | jQuery API Documentation
I can only code the client jQuery script (that will be ditribuited to the allowed domains) and the serverDomain.com/echo.php page (that is my property).
Don't do that. Use auth tokens instead that are updated regularly. Anybody can fake an HTTP referrer.
Here's a good answer on SO which covers resful api authentication: REST API Token-based Authentication
Excuse me if the title is plain idiotic with respect to the contents.
We were debating a model for an interaction-heavy site in which there will be
site.com
api.site.com
on the same server. the site.com is powered by PHP and api.site.com will be powered by an alternative web framework. The same or different servers answer the two domains.
The rendered site makes AJAX calls to api.site.com.
Securing this is easy if the application were 'all PHP'. The session feature can prevent HTTP requests that allow:
an unlogged stranger from accessing a user's data
a legitimately logged-in user from requesting another user's data
Question 1: How do you secure the internal API so that we can be sure about the legitimateness of each request?
I have googled up AJAX and same origin policy, but I didnt get far with them.
I am thinking randomly generated 'tokens' that will be acknowledged by both domains.
Question 2: Is there a specific name for this model?
You should take a look at JSONP. jQuery has a good example on it: http://api.jquery.com/jQuery.getJSON/
You need to add jsoncallback=? to the URL to make it work.
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?"
With this, you can avoid the Same origin Policy
The jsoncallback will be a timestamp, which should be echo-ed by the PHP script which outputs the JSON like this:
jsonp1277656587731(/* rest of the JSON here */);
With the number here ofcourse being the randomly generated string, or timestamp in case of jQuery JSONP
I have a web API that I want to allow any domain to submit data to. However, to keep bogus spam down I want to find some way to insure that a request stating it's from a certain domain actually is from that domain and that someone isn't trying to trick me by posting on another domains behalf.
For example, if http://example.com submits some data - thats good. If script kiddie #237 submits data claiming to be example.com - that's bad.
At first I was going to use a secret key system to HMAC sign each request - but signup is going to be open, free, and automated for this API. I'm not sure how I could tell if PersonA or PersonB really owns http://example.com and deserves the API key.
Provide a key file that they will have to upload on that domain. And you check the existence and valid data against your internal database.
Hello I am looking to build a basic API and application/apps system on my social network something like Facebook or other sites have, my site is in php/mysql. Here are some questions.
1)
Basically what I want to do is give a user a API key and secret. After I have these how can I use them in my php app to authenticate a user request which would come from there server?
2)
I can basically build an API to send a request to my server with CURL and get the result back to the page in XML or JSON or whatever, the problem is when sending the request the user would have to know the user ID they want to send to lookup data against, this is fine for an API but I am wanting to have an Apps section where the user's app site would be using the API and would be loaded into my site in the app section with an iframe, the problem is, I need to find a good way to make it where a logged in user on my site can go to the app section and go to an app and there username should be available to that page loaded in the iframe. Facebook and myspace do this somehow and many other sites; I am lost how to get around this hurdle.
Any help on any of this is really appreciated, thank you
Update:
I just had an idea, if I require a cookie to be set when a user visit's my site, then they would have a cookie and it could hold there User ID, then my API script could look for that cookie to exist and grab it's value?
If you plane on using an IFRAME, then no, your API hosted on a separate website (the website inside the IFRAME) would not be able to grab the cookie. The cookie is only visible on the website that it was set for.
I have only used Facebook API with the FBML (not the IFRAME,) but all they do their is basically replace what's in the page with the info that the "tag" is calling. I'm not sure if there is a better way, but you could possibly call a page on the app's server (say the app is hosted at http://example.com/app/, and you called http://example.com/app/?id=28318&name=John%20Maguire,) and have your API code handle it and turn it into a variable?
Maybe you should look into the source code of the Facebook API client.