2

I am working on building an API Based Architecture on PHP.

I want to make sure that the client that attempts to consume my API using a distinct API key, is the authorized client. For example, API Key "ABCD1234" is assigned to domain "example.com". If domain "fraud.com" tries to use this API Key, they should NOT be able to consume the API. How do I implement this check on the API end?

Based on what I have seen so far, it is very easy for a client to pass a referrer header to "fake" it's true identity.

Also I faintly remember when Google Maps had first launched their API, they implemented a similar technique where only the authorized URL could use the corresponding API Key. So this does not seem out of the realm of possibility.

Any help/direction would be appreciated.

Thank you,

-Saf

  • That depends on how the API is consumed. Is it a browser/Javascript based use case? A server-server use case? A client-app use case? – deceze Oct 31 '12 at 20:15
  • @deceze The API will initially be consumed in a server-server use case. However, I need to build it to support all other use cases as well. Or at least architect it in a way where other use cases can be added as business requirements change. – Sarfaraz Suleman Oct 31 '12 at 20:28
  • 2
    First strightforward approach can probably be to get an IP-address from incoming requests and make reverse DNS for them, then compare domain with white-listed ones. If you would like to eliminate reverse DNS phase, you can register your consumers by IPs, not by domains. – Stan Oct 31 '12 at 20:28
  • @Stan I did consider that and was planning on implementing that. However, dialing out to reverse DNS look-ups could be a bottleneck if the system demand grows. Plus I am at the mercy of a 3rd party system's uptime. This is still a possibility, however, I am looking for something more efficient. – Sarfaraz Suleman Oct 31 '12 at 20:30
  • Did you notice my addition about white-listing IPs instead of domains? – Stan Oct 31 '12 at 20:31
  • You could also just do the reverse DNS lookup every so often instead of doing it every time and cache the results temporarily. – Angelo R. Oct 31 '12 at 20:33
  • @Stan The white-listing IPs method works. Sorry I missed that. Using IPs instead of domains makes a lot more sense. However, I will leave the question open in case someone has a better solution. Thanks again :) – Sarfaraz Suleman Oct 31 '12 at 20:34
  • It's worth looking at OAuth, for example [here is a related answer](http://stackoverflow.com/questions/776679/using-oauth-for-server-to-server-authentication). – Stan Oct 31 '12 at 20:38

1 Answers1

1

In a server-to-server scenario, there's very little you can do with domains, because there aren't necessarily any domains involved. It's just an incoming (HTTP) request originating at some IP. That IP does not necessarily have to be tied to any host entry in the DNS system. The best you can do is to require your clients to register allowed IP addresses. Reverse DNS solutions are infeasible for various reasons, not least because they require the client to properly set up reverse DNS, which may not be practical.

If the use case is browser-side, you can use a Google Maps approach in which you require the client to include a script from your server, which checks the location of the current page in the browser. Even that is not entirely temper proof though, as anything client-side. Checking the HTTP Referer server-side is an option as well, but is easily subverted as well by anybody who really wants to. In combination it can make it difficult enough so most abusers would be deterred.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • I'd say browser-side validation using `if(document.domain == 'expected-domain.com)` is temper proof, *if* one can be sure it's actually a browser that fetches the JavaScript, and if the JavaScript cannot be fetched using XHR/Ajax (hence no support for CORS nor JSONP, for the JavaScript). However, ensuring it's a browser probably requires the visitor to get some cookie from the API's server, like by forcing authentication, which is not feasible for public services of course. Note that REFERER might also [be blank for legit requests](http://en.wikipedia.org/wiki/HTTP_referer#Referer_hiding). – Arjan Dec 16 '12 at 14:10