4

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
  • 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. Commented Mar 27, 2013 at 0:35

1 Answer 1

7

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.

5
  • 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. Commented Mar 27, 2013 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
    Commented Mar 27, 2013 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. Commented Mar 27, 2013 at 16:28
  • If the requests are being sent sufficiently quickly, perhaps SSL continuation would be a solution?
    – cdeszaq
    Commented Feb 6, 2014 at 3:16
  • Is there any point in using an HMAC when SSL is available? It sounds like you're saying that HMAC is only useful when dealing with non-secure connections.
    – Reahreic
    Commented Feb 10, 2023 at 14:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .