Bearer tokens are susceptible to theft and what you can do about it

I have been recommending JWTs to control access to REST APIs. High time for some caveats! Here is number one: most Security Token Services (STS) issue bearer tokens.

Bearer tokens are like cash: whomever is carrying them can use them. They are unlike cash in that copying and hence double-spending is easy. So how do you protect against adversaries stealing tokens and using them maliciously? Here is the immediately actionable answer: only ever send bearer tokens over TLS. Unfortunately, this does not mitigate all threats. Let's see whether we can identify some of the remaining risks and what we can do about them.

As HSTS counters the threat of downgrade to HTTP and its deployment is mostly cheap, turning it on should be a reflex: enable HTTPS, turn on HSTS.

All of the above has made it pretty difficult for the attacker to steal the bearer token in transit. What about stealing it at connection end points? Clearly we need to take measures to prevent compromise of both API consumer and producer, but I will not discuss those here. Suffice it to say that protection is likely to be imperfect, so we should move away from bearer tokens to something less susceptible to theft. This is where PoP JWT tokens come in. PoP stands for Proof-of-Possession and they bind the token to the client, the presenter in PoP-speak, to which they are issued. Some people talk about Holder-of-Key (HoK) to mean the same thing as PoP.

    |              |                         +--------------+
    |              |--(3) Presentation of -->|              |
    |              |      JWT w/ Public      |              |
    |  Presenter   |      PoP Key            |              |
    |              |                         |              |
    |              |<-(4) Communication ---->|              |
    |              |      Authenticated by   |              |
    +--------------+      PoP Key            |              |
      |          ^                           |              |
      |          |                           |              |
     (1) Public (2) JWT w/                   |  Recipient   |
      |  PoP     |  Public                   |              |
      |  Key     |  PoP Key                  |              |
      v          |                           |              |
    +--------------+                         |              |
    |              |                         |              |
    |              |                         |              |
    |              |                         |              |
    |    Issuer    |                         |              |
    |              |                         |              |
    |              |                         |              |
    |              |                         +--------------+

          Figure 2: Proof of Possession with an Asymmetric Key

The above diagram is from an RFC entitled 'Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)' and shows how it works:

  1. The Issuer or STS receives the Presenter's PoP key, presumably during client registration.
  2. The STS issues a token that includes a claim that the Presenter is in possession of this key.
  3. The Presenter sends the token to the Recipient of API producer. The token includes the key.
  4. The recipient needs to demonstrate possession of the secret key. The standard does not specify how this should be done. It offers a challenge-response exchange and a TLS handshake as possible implementations, but details are lacking.
The RFC's figure 1 shows the interactions with a secret key - the flow is the same.

I am not aware of any currently widely available implementations of PoP tokens, but I think they are worth discussing because they hold out a promise for tokens that are more resilient to theft. As soon as industrial strength implementations become available, I intend to use them.

When we have PoP, can we go back to HTTP? True, PoP has you covered on token theft, but HTTPS also protects against other things such as spoofing the API producer, so stick to it.


Popular Posts