HomePhabricator
Diffusion Comm 189a7d1ef470

[keyserver] Introduce `checkAndInvalidateSIWENonceEntry` and consume in…

Description

[keyserver] Introduce checkAndInvalidateSIWENonceEntry and consume in siweAuthResponder

Summary:
We use this function to determine if for a given nonce there's an entry in siwe_nonces AND it hasn't expired (creation_time > Date.now() - nonceLifetime). If such a row exists, we delete it so it can't be used again. We determine whether a row existed by looking at QueryResults.affectedRows.

By effectively checking and deleting in the same query we can ensure that even if there is a flood of requests with the same nonce, one and only one will pass this check.

NOTE: I'm working under the assumption that a nonce should only be valid for one request, NOT one successful request. I considered scenarios where a request may be unsuccessful initially due to whatever circumstance (maybe a network outage), but that would succeed if replayed shortly after (maybe after the network recovers), and concluded it's safest to stick to a nonce only being valid for a single request. Please correct me if this understanding is incorrect.

Depends on D6031

Test Plan:

  1. Observed siwe_nonces table entry being created on initial call to siwe_nonce endpoint.
  2. Set breakpoints in siweAuthResponder and checkAndInvalidateSIWENonceEntry.
  3. Sent request to siwe_auth endpoint from native and observed the row for the corresponding nonce being validated and deleted.

Also tested some error cases (hard coding an expired nonce from the siwe_nonces table, hard coding a nonce that doesn't exist in the siwe_nonces table, etc).

Reviewers: ashoat, tomek

Reviewed By: ashoat

Differential Revision: https://phab.comm.dev/D6032