Procházet zdrojové kódy

fix(fever): compare API key digests to avoid timing side-channel

The Fever API key was matched with a plain SQL string comparison,
which can exit early on the first differing byte. Since the Fever
protocol only sends the API key, the token is also the lookup key, so
a constant-time comparison in Go is not practical.

Compare SHA-256 digests of the lowercased tokens instead. The caller
cannot control the digest bytes, so any early exit reveals nothing
about the stored token. Matching stays case-insensitive, and
convert_to() avoids bytea escape parsing of user input.
Fred před 12 hodinami
rodič
revize
9447aaeceb
1 změnil soubory, kde provedl 2 přidání a 1 odebrání
  1. 2 1
      internal/storage/integration.go

+ 2 - 1
internal/storage/integration.go

@@ -38,7 +38,8 @@ func (s *Storage) UserByFeverToken(token string) (*model.User, error) {
 		LEFT JOIN
 			integrations ON integrations.user_id=users.id
 		WHERE
-			integrations.fever_enabled='t' AND lower(integrations.fever_token)=lower($1)
+			integrations.fever_enabled='t' AND
+			sha256(convert_to(lower(integrations.fever_token), 'UTF8')) = sha256(convert_to(lower($1), 'UTF8'))
 	`
 
 	var user model.User