Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

first of all: I am quite unsure about the questions title, so if you have a better idea, please feel free to tell (:

I would like to know about best-practise examples where services (like Twitter or co) which offer APIs and want you as developer to use some kind of API-Key prevent third parties from getting that key.

I will explain my regards with bad examples:

As far as I know Twitter and FB require you to use API-Keys for API-requests. Thats fine for server-side applications but as soon as you submit your key from a web-app or desktop-application, the key is visible for others.

Because you have to submit that key, it doesn't make much sense to super-securly store it inside your app. For the request, it has to be plain.

One thing you might do is to host your own web-service or wrapper which appends the key server side and then routes that request to the target-server.

But this is not possible if Twitter/or whatever service you are using is limiting API-requests per IP or want's to create IP-based statistics.

So to summ it up: If I was in position to create an API for others and don't want them to use SSL, what possibilities would I have to make sure their key is save and can not easily be stolen?

share|improve this question
2  
Why wouldn't you use SSL? (There's a myth out there that SSL is bad for performance. In reality, the myth is outdated and no longer terribly accurate. SSL imposes little performance overhead, in many realistic settings.) –  D.W. Aug 15 '12 at 0:36
    
The client-application would need to support SSL and depending on the dev-enviroment it can get very hard for the developer to meet the APIs requirements –  user510083 Aug 15 '12 at 0:49
    
"The client-application would need to support SSL" - That does not sound like a barrier to me. Just about every platform I've ever seen makes it easy to use SSL, e.g., by using a https: style URL or by using an existing library. Doesn't sound like a good reason to avoid SSL to me. "it can get very hard for the developer to meet the APIs requirements" - I didn't follow what you meant by this, sorry. Do you want to elaborate? What API are you talking about, and what requirements did you have in mind? –  D.W. Aug 15 '12 at 0:54
add comment

1 Answer

up vote 5 down vote accepted

The best practice is:

The basic idea. Create an API key (a 128-bit symmetric key) for each separate user account. This key needs to be securely stored on the server, and also securely stored on the user's client.

For each request made by the client, add an extra request parameter that has a "signature" on the entire request. The "signature" should be calculated as S = MAC(K, R), where K is the API key and url is the entire request, including all request parameters. Here MAC should be a secure message authentication code algorithm, such as AES-CMAC or SHA1-HMAC.

It is the client's responsibility to compute the signature and append it to the request; it is the server's responsibility to verify the signature and ignore any request with an invalid signature. You may also need to include an additional parameter with the request that identifies the user account making the request.

This will provide authentication of the request, but not confidentiality or replay prevention, and the client does receive an authenticated response from the server.

I suggest sending all requests over https (not http). This will provide an additional level of security against a number of tricky cases. The performance implications of doing this are less than you might think -- SSL has less performance overhead than most people think -- so don't discard this idea on performance grounds unless you've actually measured the performance overhead and found it to be unacceptable.

Additional things to watch out for. You may want to use a one-time-use nonce, to prevent replay of authenticated requests. I suggest using a cryptographic-strength random value (at least 64 bits long). This is unnecessary if you are using https.

Make sure your server is written to defend against host-parameter pollution (HPP) attacks. For instance, it should reject any request with multiple request parameters of the same type (e.g., http://example.com/foo.html?name=x&name=y). Also, when writing server code, be careful when creating new requests based upon a request you received. For instance, before processing each request, your server code might validate that the request comes with only the expected list of parameters and nothing more; discard duplicate parameters or unexpected parameters before processing the request.

Watch out for concatenation flaws if you decide to protect multiple values with the message authentication code.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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