5

I have a REST API backend which has HTTPS (and blocked HTTP) and use JWT as the authentication mechanism. Client side is iOS/Android App. I want to add a layer of safeguard on critical API by using client nonce to prevent (mostly) resubmission (unintentionally calling the same API twice due to bad network/UI) and (maybe) replay attack. The current details are following.

(All REST call are though HTTPS)

  1. client make an API call using username and password to exchange for a JWT from server side
  2. client use the JWT obtained (HTTP header) and make subsequence API call to server
  3. backend server check the JWT and execute the request

The current issue is anyone who can intercept the HTTP package can replay the API call. Moreover, in situation with bad network, client may press the submit/confirm button twice and resubmit the request.

What I propose is following:

  1. client make an API call using username and password to exchange for a JWT from server side
  2. client use the JWT obtained + a client-generated nonce and make subsequence API call to the backend server.
  3. backend server check the JWT first and then the nonce. Let's assume we have a k-v store with TTL like Redis.
  4. If the nonuce exists in Redis, we reject the request. If not, we accept the request and set the nonuce in Redis with some predefined TTL (say 1hr?) so that a replay will be rejected.

I have to admit I have very little knowledge on security. I want to know if this proposal is legit? Or I miss something important? If my idea is ok, what is the best algorithm to generate the nonce? Do server side need to somehow "decode" the nonce to see if it fit the protocol before comparing it against Redis?

  • 2
    Since you're using https why are you worrying about someone to "intercept the http package"? https as such is already replay safe. – kaidentity Aug 5 '16 at 15:02
  • ok, so my remaining concern remain is client side resubmission – mingchuno Aug 5 '16 at 15:19
5

A client-side nonce presents three difficulties:

  • how does the client know when to generate a new nonce? (What actions constitute a new request such that a new nonce should be generated for it?)

  • how does the server know what's a valid nonce? Can a hypothetical attacker-supplied 4gb blob be a nonce?

  • how does the server know how many nonces to keep and for how long?

A server-provided nonce provides two benefits:

  • less for the client to do
  • the server knows what to expect next

The server doesn't have to keep a record of all nonces, just the current one, and it can be deleted when the first valid request with it arrives. A new nonce can be sent with the response.

This model enforces a one-request-in-flight interaction model. Should there be a desire for multiple concurrent requests, the server can produce a block of nonces, but the challenge again is that client needs a model for differentiating between unique requests, ensuring that each user action doesn't result in pulling a new nonce from the local pool. This difficulty should suggest structuring the app in a way such that only one nonce-required request be in flight at a time.

0

(All REST call are though HTTPS)

Then you're already protected against replay attacks.

  • https prevents replay attacks only at the network level, i.e. a man-in-the-middle can't replay an intercepted https request, thanks to the protocol. But the client (hacked, network problems, etc) can resend the same original request, seen as different requests from a http point of view. – user1075613 Jan 20 at 1:27

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.