views:

195

answers:

4

Question: Is this API authentication technique easily hackable?

    apiKey = "123456789"
    apiCallId = "1256341451"
    apiSecret = "67d48e91ab2b7471d4be2a8c2e007d13"
    sig = md5(apiKey + apiCallId + apiSecret) = 09c297a354219f173bfc49c2e203ce03

where

  • apiKey: some unique identifier for the user
  • apiCallId: a unique integer that must be increasing in value (e.g. UNIX time stamp)
  • apiSecret: string known only to the user, and us - not passed in URL
  • sig: "unhackable" signature of this API call - MD5 hash

Example API call:

http://api.domain.com/?apiKey=123456789&apiCallId=1256341451&sig=09c297a354219f173bfc49c2e203ce03&param1=x&param2=y

This API does not require a session, and is not designed for a 3rd party to use on behalf of a user. Instead, it is to be used by the user themselves.

I really like the simplicity of this. The requirement of apiCallId being unique, and always increasing means reusing a sig is not possible, so I feel like it is secure (protected against replay attacks), but I am not an expert.

Other APIs use all of the GET parameters sorted alphabetically when calculating the sig, but I do not see why this is necessary when including apiCallId.

Please try and hack this now before it is implemented and released :-)

I welcome any feedback, suggestions and security education.

A: 

Well suppose i knew the secret, then i could generate the sig and pass it. What were doing for one of my startups is taking the sig param even further by making the sig rely on the other parameters and also a requestID (UUID) and timestamp and store that UUID(security reasons for a couple of hours to deny the hacker of calling the same function over and over again). This way you cant call the same call again, you would have to generate a new UUID and if the hacker replaces the UUID in the param the sig invalidates, and he does not know how to generate the sig because, other than secret, we are also generating signature based on an internal key which is 30 characters in length. So essenity

MD5(Alphabetical List of Params + APiKEY + callID + Secert + someLonginternalKey)

not sure if i answered your question but thats another way of doing security for api

Faisal Abid
P.S Shameless self promotion , I will be taking about this on Riadventure (Riadventure.com)
Faisal Abid
"Well suppose I knew the secret" is game over in most APIs.Your solution definitely seems more secure, but is it "security through complexity"? I don't want to complicate the process unnecessarily. Why is the advantage to including all of the parameters? Why does the extra key make it less prone to being hacked?
Peter Sankauskas
The extra key isnt required just some extra padding, you can ignore that. However by hashing the parameters in the signature, this ensures the data you are passing (i.e param1 param2) it's integrity is kept and your sure that no one changed it (man in the middle) like the other post was saying.
Faisal Abid
+2  A: 

No. The integrity of the other parameters (param1 and param2 in your example) is not protected. An attacker can intercept the call and alter these as he likes before forwarding it. The apiCallId only prevents replays, not alteration of the first call.

I'm no expert. If I saw that immediately, there are probably other problems lurking.

erickson
Ah-haaa... interception is the reason.
Peter Sankauskas
But what is to stop interception of any API call even if all of the parameters are used in the signature?
Peter Sankauskas
Kirk Broadhurst
I'm saying if a MAC were computed over the entire message, an alteration to any part of the message would be detectable.
erickson
+6  A: 
Jack Lloyd
Awesome answer, and I love the technical detail. 'erickson' pointed out that interception (man-in-the-middle) is possible with the above. Do you have any recommendation of how to prevent this type of attack? I guess this goes beyond the original question. Does using HTTPS (and not HTTP) cover it?
Peter Sankauskas
If the MAC covers all the data, _and_ there is no second set of input which canonicalizes to the same input to the MAC (this is important, as Amazon learned), and you ensure there is no way to do replay attacks (your counter scheme, implemented properly, seems OK), and your MAC is secure, then you should be safe against MITM. That's because an attacker has no options - they can modify a param or API value and try to send it on, but there will be no way for them to generate the correct MAC value, so the call (should be) rejected.
Jack Lloyd
I'd assume you enforce the call id is always incrementing by a database table. Just be careful to update it only upon accepting a valid mac. Otherwise any random attacker could send apiKey=your_id and apiCallId=9999999999999999... and a garbage MAC value and cause an easy denial of service.On HTTPS: you can use it, do so - for one thing, it will protect the confidentiality of the API inputs (and the RPC responses), and just generally make any attacks on your auth scheme much harder.
Jack Lloyd
`H(msg || K)` is much better than `H(K || msg)`, but it's still not great - if an attack is found to generate collisions in `H()` then this MAC becomes insecure (and there **is** such an attack against MD5). So I think you've buried the lede - "use HMAC" should be near the top.
caf
..and Nate Lawson has just put up a post (http://rdist.root.org/2009/10/29/stop-using-unsafe-keyed-hashes-use-hmac/) saying exactly the same thing - `H(msg || K)` (aka "secret suffix") is broken with MD5.
caf
A: 

I would suggest to use digital signatures in this case since they're more appropriate. A digital signature over for example the apikey is more than enough. You dont even need the apisecret and the hash of it. You'd only have to make sure that the digital signature stays private (just like the md5 hash).

If you want to prevent replay attack, you need some kind of randomness in every request. So I would suggest the following:

Server -> API: Nonce (= some random number)

API -> Server: Enc(nonce + digital signature)

this is encrypted with the public key of the server and the digital signature is placed with the private key of the server.

Now you cannot have a replay attack. However there is still the problem of a man in the middle attack, but fixing this is not so trivial (but quite doable). So depending on the level of security you want/need you can adapt your technical measures.

Henri