Skip to content

Geo JWTs (JSON web tokens) do not expire

Summary

The Geo API (and HTTP cloning mechanism once https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3116 is finished) uses JWT authorization. The Geo secondary has a key, which it uses to generate tokens which are intended to be short-lived. Expiring them aggressively means that the risk associated with exposing such a token is limited. Geo expects these tokens to live for a minute or so.

Steps to reproduce

Capture a JWT using tcpdump, or generate one, e.g., with:

::Gitlab::Geo::BaseRequest.new.headers['Authorization']

Wait for 120 seconds

Use the token for authentication, or attempt to decode it:

::Gitlab::Geo::JwtRequestDecoder.new('token here').decode

What is the current bug behavior?

Tokens are valid for as long as the secret key does not change

What is the expected correct behavior?

Token should expire after 60 seconds

Possible fixes

We ask the JWT gem: http://www.rubydoc.info/gems/jwt to verify_iat when decoding the token. It seems we want that to cause the token to be invalidated, but that's not what iat is for: https://tools.ietf.org/html/rfc7519#section-4.1.6

What we actually want to use is the exp claim: https://tools.ietf.org/html/rfc7519#section-4.1.4 . Perhaps also the nbf claim: https://tools.ietf.org/html/rfc7519#section-4.1.5 , to ensure the token cannot be used before its issuance.

/cc @stanhu @brodock @toon @jarv @dbalexandre

I believe we use JWTs elsewhere in the codebase as well. We should audit these places to ensure that we're not making the same mistake.