GH GambleHub

JWT: estrutura e vulnerabilidade

1) O que é o JWT e onde ele é usado

O JWT é um contêiner de afirmações (claims) compacto no formato 'Base64Url (header). Base64Url(payload). Base64Url(signature)`.

Usado para:
  • JWS (tokens assinados - autenticidade/integridade),
  • JWE (tokens criptografados - privacidade),
  • OIDC/OAuth2 como acesso/ID de tokens e autenticação service-to-service.

Os benefícios são autonomia, capacidade de armazenamento, pequenas despesas gerais. Contras: risco de validação errada, malas de retirada complexas.

2) Estrutura JWT

2. 1 Título (header, JSON)

Mínimo: algoritmo e ID da chave.

json
{ "alg": "ES256", "kid": "jwt-2025-10", "typ": "JWT" }

'alg': algoritmo de assinatura/criptografia (RS256/ES256/PS256/HS256 etc.).
'kid': ponteiro da chave (para rotação JWKS).
As fontes de chave opcionais são 'jku', 'x5u' (consulte vulnerabilidades do parágrafo 6. 3).

2. 2 Carga útil (payload, JSON)

Marcas padrão:
  • `iss` (issuer), `aud` (audience), `sub` (subject)
  • 'exp', 'nbf', 'iat' (emitido)
  • 'jti' (ID de tocador adequado para críticas)
  • marca domain: «scope/roles», «tenant», «kyc _ level», etc.

2. 3 Assinatura (assinatura)

JWS = `sign(base64url(header) + "." + base64url(payload), private_key)`

Verificação: chave pública estritamente apropriada e exatamente o algoritmo que o servidor espera.

3) Invariantes básicos de verificação

1. O algoritmo é capturado pela configuração do servidor de recursos (allow-list), em vez de confiar no conteúdo 'header. alg`.
2. Verificar «iss» e «aud» para a coincidência exata, «exp/nbf» - tendo em conta o pequeno «clock _ skew» (£30-60s).
3. Recusar o tocador sem 'kid' apenas se a chave for única e não houver rotação; senão exigir 'kid'.
4. Não confiar em nenhuma marca sem autorização no nível de objeto (BOLA-first).
5. Parsing - depois da criptoprovia; verificação básica de tamanho antes da decodificação.

4) JWS vs JWE

JWS: assinado, mas lemos. Não coloque em payload PII/segredos.
JWE: criptografa payload; a integração é mais difícil, o modelo-chave é crítico.
Na maioria das APIs é suficiente JWS + proibição de dados sensíveis no payload.

5) Ciclo de vida do token

Access: prazo curto (5 a 30 minutos).
Refresh: mais longo (7-30 dias), rotate-on-use (descartável), armazenar «lista negra» 'jti/sid'.
Revocation: listas de 'jti' com TTL, introspecção para opaque-tokens, redução de 'exp' em incidentes.
Rotação de chaves: JWKS com sobreposição (antigo + novo), consulte Rotação de chaves.

6) Vulnerabilidades frequentes e como fechá-las

6. 1 'alg = none '/troca de algoritmo

Essencial: o servidor confia no campo 'alg' e aceita o token não assinado.
Proteção: rígido allow-list algoritmos no servidor; rejeitar 'none' e valores inesperados.

6. 2 RS256→HS256 swap (simetrização)

Essencial: O agressor substitui 'alg' por HS256 e usa a chave pública como segredo HMAC.
Proteção: vincular a chave à configuração do algoritmo; não misturar provedores simétricos/assimétricos em um único 'kid'.

6. 3 Injeção de chaves ('kid/jku/x5u')

Cenários:
  • 'jku' indica um JWKS controlado por um intruso (subtrair sua chave).
  • 'x5u '/' x5c' abuso de certificados externos.
  • 'kid' com injeção de caminho/SQL ('".../.../privey. pem"' ou '"'OR 1 = 1 - "').
Proteção:
  • Ignorar os 'jku/x5u' remotos ou filtrar por uma lista rigorosa de domínios.
  • 'kid' usar apenas como chave no diretório local (tabela/kesh), sem caminhos de arquivo/concatenações SQL.
  • JWKS carregar com URL confiável, TTL curto, assinatura/canal pinning.

6. 4 Segredos fracos HS256 (força bruta)

O segredo HMAC é curto/pato → trocar a assinatura.
Proteção: usar assimetria (RS/ES/PS) ou comprimento de segredo ≥ 256 bits, segredos apenas em KMS.

6. 5 Marcas ausentes/não-aleatórias

Não há 'aud '/' iss '/' exp' → o token de serviço cruzado é ou infinito.
Muito longo 'exp' → risco de comprometimento.
Proteção: exigir um conjunto completo de marcas, 'exp' curto, 'nbf '/' iat' validar com 'clock _ skew'.

6. 6 Replay e roubo de token

Essencial: interceptação/repetição de token (fuga em logs, XSS, MitM sem TLS).

Proteção:
  • TLS везде, `Secure`+`HttpOnly` cookie, SameSite=Lax/Strict.
  • DPoP/PoP (vinculação do tocador à chave do cliente) e/ou mTLS para os parceiros.
  • Curtas 'exp', rotação refresh, device-binding.

6. 7 Fugas via XSS/armazenamento

Essência: armazenamento JWT em 'localStorage '/' sessionStorage' → está disponível JS.
Proteção: Armazenamento de tocas access em HttpOnly-cookie (se possível cookie-model) + CSP/Trusted Types rigoroso.
Para SPA sem cookies - isolar o token na memória, viver minimamente, proteger contra XSS.

6. 8 CSRF

Essencial: quando as sessões de cookie são solicitadas por um site de terceiros.
Proteção: toquenis anti-CSRF (duplo submit), 'Origin/Referer', filtros Fetch-Metadata.

6. 9 Oversize/abuso de tamanho

A essência é um grande payload/cabeçalho DoS para parsing.
Proteção: limites de tamanho de cabeçalho/corpo, early-rejt 431/413, conjunto de marcas fix.

6. 10 Troca de 'typ '/' cty'

Essência: confusão de tipos ('typ:' JWT '), objetos JOSE aninhados.
Proteção: ignorar 'typ/cty' para segurança, e confiar em algoritmos fixos e marcações.

7) Armazenamento e transferência de tokens

7. 1 API de servidor (machine-to-machine)

mTLS/HMAC, de preferência assimetria para JWT, canais através de mesh.
Armazenamento de chaves - KMS/HSM, rotação programada, JWKS com sobreposição.

7. 2 Clientes de navegador

HttpOnly Secure Cookie для access/refresh; TTL curtos; atualização por «silent refresh» com «SameSite=None» apenas sob HTTPS.
CSP rigoroso, Trusted Types, proteja contra XSS; SPA - se possível, não armazenar o token no disco.

8) JWKS, roteiro e revisão

O JWKS é publicado por um utilizador automático; os consumidores escondem por 5-15 minutos.
Plano de rotação: adicionar um novo 'kid' começar a assiná-lo em N dias para remover o antigo do JWKS purge.
Levantamento: listas de 'jti/sid' c TTL; no incidente, reduzir temporariamente 'exp' e força-logout (deficiente refresh).

9) Multi-tenant e minimização de dados

Incluir 'tenant '/' org' apenas se for necessário pela arquitetura; caso contrário, puxar os atributos do PDP por 'sub'.
Nada de PII; um conjunto mínimo de marcas → menos risco de fuga e corelação.

10) Folha de cheque de validação prática (servidor do recurso)

  • Parsim somente após verificar a assinatura e os limites básicos de tamanho.
  • 'alg' da configuração; Rejeitar os inesperados.
  • Verificar 'iss' n' aud ' ' exp ' ' nbf 'n' iat' (com 'clock _ skew').
  • Verificar 'kid' pelo diretório local/JWKS (TTL curto).
  • Filtrar/normalizar ponteiros externos ('jku/x5u' - apenas allow-list).
  • Limitar comprimento/composição de marcas (padrão).
  • Aplicar autorização de objeto para recurso (BOLA-first).
  • Logar 'kid', 'sub', 'aud', 'iss', 'jti', 'exp', 'tenant', 'trace _ id' (sem PII).
  • Métricas de erro de assinatura, atraso, auditoria de rotação.

11) Exemplos de políticas seguras (pseudo)

11. 1 Configuração de expectativas do algoritmo

yaml jwt:
expected_issuer: "https://auth. example. com"
expected_audience: ["wallet-service"]
allowed_algs: ["ES256"] # fix the jwks_url: "https ://auth. example. com/.well-known/jwks. json"
jwks_cache_ttl: 600s clock_skew: 60s required_claims: ["iss","aud","sub","exp","iat"]

11. 2 Rejeição remota 'jku/x5u'

yaml reject_untrusted_key_sources: true allowed_jku_hosts: ["auth. example. com"] # if absolutely necessary

11. 3 Exemplo de lista de comentários (Redis)

pseudo if redis. exists("revoke:jti:" + jti) then deny()
if now() > exp then deny()

12) Observabilidade e forensica

Метрики: `jwt_verify_fail_total{reason}`, `jwt_expired_total`, `jwks_refresh_total`, доля `kid`.
Logi (estruturado): 'iss/aud/sub/kid/jti/exp/tenant/trace _ id', causa da falha.
Dashboards: «em breve», aumento de erros de validação, distribuição por região/cliente.
Alerts: altura de 'verify _ fail' (assinatura/algoritmo), erros de JWKS, proporção de tokens vencidos.

13) Antipattern

Confiar em 'alg' do token; suportar 'none'.
Acesso de longa duração e falta de rotação refresh.
HS256 com segredo curto/segredo em ENV sem KMS.
Aceitar 'jku/x5u' de qualquer domínio; carregar dinamicamente o JWKS sem allow-list.
Coloque PII/segredos no payload JWS.
Armazenar tokens em 'localStorage' se houver riscos XSS.
Abafar erros de validação (devolver 200 com «soft error»).
Falta de verificação de BOLA e dependência apenas de 'scope/role'.

14) Especificidades do iGaming/Finanças

Marca: 'kyc _ level', 'risk _ tier', 'tenant', 'aud' rigoroso.
TTL curtos para transações write (depósitos/conclusões), PoP/DPoP ou mTLS para rotas críticas.
Auditoria regulatória: registros de entrada/rejeição imutáveis, armazenamento de logs nos limites da região.
Os parceiros/PSP têm chaves individuais/' aud ', chaves para tenante e JWKS individuais.

15) Folha de cheque pró-prontidão

  • Rígido allow-list algoritmos; 'none' não é permitido.
  • 'iss/aud/exp/nbf/iat/jti' são verificados; curtas 'exp'.
  • JWKS com sobreposição, curto TTL de cachê; monitoramento da parte 'kid'.
  • Refresh — rotate-on-use; listas de 'jti/sid' com TTL; playbook de comentários.
  • PoP/DPoP ou mTLS em rotas críticas.
  • HttpOnly-cookies para navegador, CSP/Trusted Types vs XSS; Proteção CSRF.
  • Sem PII no payload; um conjunto mínimo de marcas.
  • Métricas/logs de validação e falha; alert JWKS/verify _ fail.
  • Testes de cenários negativos: RS→HS swap, 'kid' -inecção, 'jku' spoofing, oversize, clock-skew.

16) TL; DR

Fixe o algoritmo e as chaves no lado do servidor, não confie em 'alg' do token, exija 'iss/aud/exp/nbf/iat/jti'. Rotue as chaves através do JWKS com sobreposição, mantenha os tokens curtos e refresh descartáveis. Guarde os tokens com segurança (HttpOnly-cookie para web), minimize as marcas, não coloque o PII. Feche 'jku/x5u/kid' - controladores, evite HS256 com segredos fracos, adicione PoP/DPoP ou mTLS em caminhos críticos e faça sempre testes BOLA ao nível do recurso.

Contact

Entrar em contacto

Contacte-nos para qualquer questão ou necessidade de apoio.Estamos sempre prontos para ajudar!

Telegram
@Gamble_GC
Iniciar integração

O Email é obrigatório. Telegram ou WhatsApp — opcionais.

O seu nome opcional
Email opcional
Assunto opcional
Mensagem opcional
Telegram opcional
@
Se indicar Telegram — responderemos também por lá.
WhatsApp opcional
Formato: +indicativo e número (ex.: +351XXXXXXXXX).

Ao clicar, concorda com o tratamento dos seus dados.