I am creating a web service, which handles various requests from web clients. The client and server share a big secret key S, and when one part wants to send data, it calculates the token as follows:

T = HMAC(HTTP body || Request Timestamp, S)

So when a part receives http request it recalculates T from the http body, and the timestamp from the Date http header field, and compares it, with the HMAC digest it received. If the digests are equal AND the time offset of the timestamp and the time the request was received is lower than a specified threshold grant the request. Else deny it.

Is this secure? Assuming that the attacker cannot forge the Date header since it is protected from the HMAC, plus the time limit offset(for replay protection), i think it is ok.

Assuming, that the above protocol has no flaws, how long should i set, the valid threshold offset? Say for example 5 seconds is ok?

  • 1
    For true protection against replay attacks, you can just generate a unique nonce. Persist that nonce somewhere (if you also have an expiry timestamp in the message, this can be a temporary cache like memcache). If you ever see it again, the request has been replayed. Mar 27 '13 at 0:35

If you do your protocol over plain HTTP, then attackers meddling with the communication may drop, duplicate or reorder requests, within your time frame. They may also send to the client (respectively the server) some of its own requests as if they were responses from the server -- depending on your protocol, this may or may not be a problem, but it could be devastating.

You can lower the validity range of requests and responses by rejecting time stamps which are off by too much an amount, but this requires that client and server are properly synchronized, something which cannot be guaranteed on a general basis (many computers "out there" are off by several minutes, even hours, even years in some cases). So you cannot make the timestamp validity range sufficiently low to ensure decent security. To sum up, your protocol cannot be really resistant against replay attacks and variants, when played over an unprotected transport medium like plain HTTP. You can do some mitigations, to some extent, but at the cost of usability issues (because of a possible lack of clock synchronization).

The solution is then: use SSL (aka HTTPS in a Web context). SSL will give you all the replay protection you may wish for; it also brings encryption. With SSL, your homemade HMAC become redundant and you could simply forget them altogether.

  • SSL is not a solution since the requests are not persistent, and there will be many of them, so the overhead of ssl is unacceptable. I am thinking to implement challenge response since this overcomes the problems of the protocol i mentioned above. Mar 27 '13 at 15:05
  • 3
    "Overhead of SSL" is (very) often (widely) overestimated; I encourage you to make actual measures on your situation. Regardless, security against replay attacks and similar attacks requires some machinery, and even if you do not use SSL you will have to implement something which will be very SSL-like, notably for performance.
    – Tom Leek
    Mar 27 '13 at 15:46
  • I agree, but the protocol is a simple request response, with tiny requests and responses, and the requests are being sent periodically often. So in this case i think that the SSL overhead is unacceptable. Plus the fact that i do not need encryption. Only authentication, and replay protection. Mar 27 '13 at 16:28
  • If the requests are being sent sufficiently quickly, perhaps SSL continuation would be a solution?
    – cdeszaq
    Feb 6 '14 at 3: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.