1

I have two sites and an API that sends data back and forth between the two. The API is only used on the back end, and the user will not interact with it at all. What I would like to do is ensure that any requests made to this API (on either site) came from the other site and no where else.

Right now I have an API key stored on each site that must be sent with the request; without the key the request will be rejected. Still I feel that this is not secure enough because the API key can become compromised.

What steps can I take to verify that my API requests are coming from the correct source? The language is PHP.

  • Are the API requests made server to server or from the browser once the user has loaded the page? If it's server only you could just limit requests to the second server's IP address and be finished with it. – thorsten müller Sep 1 '16 at 15:47
  • For server - server this is a good start. You biggest risk is losing that API key. So make sure your connection is for example over https so it's not easy to be in the middle. Also you need to prevent from losing your key when for example your website gets hacked by a scripting error. If you want to improve this process it seems wiser to start using for example an SSH tunnel / vpn in between them. But I see your biggest risk at this moment that users seem to connect to those servers as well (not to the api but to the server), so there is your biggest attack surface. – Luc Franken Sep 1 '16 at 15:53
  • @Evan if my api key becomes compromised then there is effectively no security. – Chris Sep 1 '16 at 15:56
  • @thorstenmüller Limiting by IP does not necessarily prevent a malicious request; an attacker may be able to spoof the address. – Marvin Sep 1 '16 at 16:03
  • 1
    Note: in cryptography, we assume you won't lose your keys. This assumption is so great that when we say "Alice verifies that a message came from Bob," it's actually short hand for "Alice verifies that a message came from someone who knows what Bob knows." If your adversary knows as much as your ally, encryption falls apart and you are now highly dependent on physical security to provide integrity. – Cort Ammon Sep 1 '16 at 17:47
2

There are many ways to skin a cat, but for your context I suggest the following.

First, authenticate the servers with TLS/SSL. Obviously, this only authenticates the server, not the client; so, to authorise a request, the server should contact what it expects be the origin server and seek confirmation.

API Request Authorisation

The exchange would look like this:

Client              Server B            Server A
   | ----- data -----> |                   |
   |                   | --- validate ---> |
   |                   | <------ ok ------ |
   | <--- response --- |
  • An unauthenticated client makes an API call to a server authenticated via SSL/TLS, the request contains an auth token.
  • The receiving server takes the auth token and contacts what should be the server that generated the request and asks whether it generated the auth token. This origin server has now also been authenticated via SSL/TLS.
  • Depending upon whether the auth token was validated, the API request can be approved/denied.

Conversational Syntax

  • Client -> Server B: "Do X, Y, Z. Auth:abdhs67ruhbf"
  • Server B -> Server A: "Did you send me a request with Auth:abdhs67ruhbf"
  • Server A -> Server B: "Yes."
  • Server B -> Client: "Result: A, B, C."

This obviously has a high latency cost if the servers are far away from one another.

Additional Notes

  • As User949300 suggests, it would be advisable to place an expiration time on auth codes when they are generated (e.g. 24-hour TTL) so that attackers don't try to exploit old tokens.

  • For the same reason, when the response to an API call is received, the token used to make the call should be revoked.

  • Thanks, this makes a lot of sense! Sorry for a beginner question, but how would I go about authenticating the servers with TLS/SSL? Both sites have valid SSL certificates, is this the same thing? – Chris Sep 1 '16 at 16:09
  • 1
    @Chris Yes, just make sure the API calls are being made with HTTPS not HTTP. – Marvin Sep 1 '16 at 16:11
  • 1
    Good answer. PayPal works more or less like this. You might want to somehow timestamp the requests so hackers dont spoof you with 2 day old messages. – user949300 Sep 1 '16 at 20:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.