简体   繁体   中英

PHP - Securely sending request/response between 2 servers?

Summary: I've created an app in PHP. It's lead management system for a call center. I now need to allow a partner to be able to add new leads to the app by integrating our app with their proprietary CRM. In short, I guess I need to build an API for my app.

The easiest approach I can think of is a simple HTML post. Would this be considered too insecure? If so, what would be best approach for this type of situation?

Thanks for any help,

Andrew.

Through your quest to build an API, you'll most likely come across some of these. I'm going to outline the concepts that might come in very handy to actually build an API that is usable, and that follows open standards (which, in turn, makes it trivial for third-party to adapt existing code to interact with it).

API dispositions

The first keyword is: SSL. Don't ever think of not using it. This provides a secure socket layer on which communication can happen in a secure fashion, and consequently makes eavesdropping and MitM attacks significantly more difficult to conceive.

No matter what, do not skip on this. Certificates cost less than $60/year, so it is not exactly costly, and can save you a lot in the long run.

In terms of server techs, use what you want. Your main requirement is a webserver that can handle the four common HTTP verbs: GET, POST, PUT, DELETE. I'll explain why in a moment.

API authorisation

This one is the contentious field, as lots of people "think they have a secure way to do so". The answer is simply not true. The point of your authentication is to allow a client to easily authenticate with their credentials, but to prevent a third-party who is not privileged from doing so.

Simply adding an API key to the feed will just lead to someone eventually getting hold of it. I have seen this specific thing so many times that I strongly advise against it, especially as there are significantly easier options.

I'll go over a couple of things, labelling them as (A) or (S) , respectively for Authentication and Signature. Signing is the method used to render your request tamper-proof. Authentication proves who you are.

HMAC-SHA512 signing (A) (S)

This technique is used by Amazon for all their S3/AWS APIs, and is a very lightweight method of signing and authenticating a request. I personally find it relatively ingenious.

The basic idea:

  1. Round up all the GET and POST fields (including your public key)
  2. Sort them alphabetically
  3. Concatenate them using URLEncode or equivalent
  4. Perform a HMAC hashing cipher on the data, with your private key as the key of the HMAC.
  5. Append the result of 4 to your request.

This is simple and ingenious. What it guarantees:

  1. You cannot change the request without knowing the private and public keys
  2. You cannot change the key without changing the request

This neatly wraps both issues using the same HTTP request at the cost of one reserved GET/POST field. Amazon also requires the presence of a Timestamp in the request, which prevents replay attacks. Neat!

(For the reference: HMAC- ALGO = ALGO( (key XOR PAD) concat ALGO(key XOR PAD2) concat message) . ALGO can be any hash cipher - SHA256 is preferred for its lightweight nature)

OAuth (A)

You've probably heard of it. the idea is simple: you get given a key and secret. This allows you to queue up for a temporary token. This token is then used to perform requests.

The main advantage of this is that lots of libraries exist to handle it, both client-side and server-side. The other advantage is that OAuth has two modes of operation: two-legged (server->server without client interaction) and three-legged (client->server->server).

The main drawback is 2 HTTP requests to get a token.

Simply sending private keys through (A)

... Leads to replay attacks. don't consider it.

A mixture of methods is a possible things. The HMAC signage is awesome when combined with OAuth, for example!

API conception

API endpoints these days follow two main standards: SOAP (XML-RPC), or REST. If you are building an endpoint to post leads, you may as well build the corresponding API to read leads and to delete them for the future.

Your API would therefore take the form:

 /my/endpoint/
  - GET: gets a list of leads
  - POST: creates a new lead
 /my/endpoint/ID/
  - GET: get lead info
  - PUT: modifies lead
  - DELETE: deletes the lead

This allows you to future-proof your API conveniently as well.

A HTML post will suffice, that's not a problem. It would be even better if you're able to use HTTPS to ensure the transferred data is encoded, but this isn't critical.

The most common way of securing this kind of API is to provide a shared 'secret' or 'key', which is used to encode a hash. You'll then be able to verify that the request came from a trusted source, but it's up to the user to ensure that they keep the shared key a secret.

eg Users of your API will need to:

// build hash string to be sent with API POST request (use a sensible combination of values)
$string = sprintf('%s.%d.%d.%d', $username, $orderId, $currentTimestamp, $price);

// hash
$encodedString = sha1($string);

// concatenate with shared key
$stringWithKey = sprintf('%s.%s', $encodedString, $sharedKey); // GET KEY FROM SECURE PLACE

// hash again to get hash that will be sent with the POST request
$hash = sha1($stringWithKey);

Then you'll perform the same logic at your end from the POST values provided and verify that their hash matches the hash that you build with the user's shared key.

This is exactly what an API is for. I'd make a unique key per external account and require that API key for each $_GET or $_POST transaction that is sent to your server.

Might want to build an API management console while you're at it. Oh and don't forget the separate DB table for the API keys.

When you're done it'll be something like:

https://api.mysite.com/index.php?key=r328r93fuh3u4h409890fj34klj&other=something&another=somethingelse

You get the idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM