Utilo

Como funciona o JWT e como decifrar um token com segurança

Compreender a estrutura dos Web Tokens JSON, como as assinaturas são criadas e verificadas, reivindicações comuns, armadilhas de segurança e como decodificar um JWT.

· 6 min de leitura

JSON Web Tokens (JWTs) estão em todos os lugares: OAuth e OpenID Connect logins, API gateways, single sign-on entre microsserviços e sessões de aplicativos móveis. Também são amplamente incompreendidos. Os desenvolvedores decodificam um token, veem um JSON legível e se perguntam se isso é um problema de segurança; outros armazenam dados confidenciais em tokens, assumindo que eles estão criptografados. Este artigo explica exatamente o que é um JWT, como ele é validado e como inspecioná-lo sem criar riscos.

As três partes de um JWT

Uma JWT parece três cordas aleatórias unidas por pontos:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImV4cCI6MTkwMDAwMDAwMH0.Kx8...

Cada parte é codificada com Base64URL:

  1. Header JSON descrevendo o tipo de token e o algoritmo de assinatura, por exemplo {"alg":"HS256","typ":"JWT"}.
  2. Payload JSON contendo reivindicações: declarações sobre o usuário e o token, como {"sub":"42","exp":1900000000}.
  3. Signatura bytes calculados a partir do cabeçalho e da carga útil com uma chave secreta ou privada.

Base64URL é uma variante de [Base64] (explicado) que usa - e _ em vez de + e / e deixa de ser um padding, para que os tokens possam ser colocados em URLs e cabeçalhos sem escapar.

Crucialmente, o cabeçalho e a carga são apenas codificados, não criptografados. Qualquer um que tenha o token pode lê-los. Coloque um token em um [JWT decodificador] ((/ ferramentas / jwt-decodificador) e a carga útil aparece instantaneamente que é por design.

Como funciona a assinatura

A assinatura é o que torna um JWT confiável. O emissor pega o cabeçalho codificado e a carga útil, une-os com um ponto, e assina essa cadeia.

Com o HS256 (HMAC com SHA-256), o emissor e o verificador partilham uma chave secreta:

signature = HMAC-SHA256(secret, base64url(header) + "." + base64url(payload))

Com RS256 ou ES256, o emissor assina com uma chave privada e qualquer pessoa pode verificar com a chave pública correspondente, muitas vezes publicada em um ponto final JWKS, como https://login.example.com/.well-known/jwks.json. Algoritmos assimétricos são preferidos quando muitos serviços precisam verificar tokens, mas apenas um deve emitir.

Quando um servidor recebe um token, ele recompõe ou verifica a assinatura. Se apenas um caractere da carga útil mudar digamos que um atacante editou "role":"user" para "role":"admin" a assinatura não corresponde mais e o token é rejeitado.

Reclamações registadas que deve saber

A especificação JWT (RFC 7519) define nomes de reivindicações padrão:

  • iss (emissor): quem criou o token, por exemplo https://login.example.com.
  • sub (assunto): sobre quem é o token, geralmente uma ID de usuário.
  • aud (audiência): para quem o token é destinado, como api.example.com.
  • exp (expiração): o tempo após o qual o token deve ser rejeitado, em [segundos Unix] ((/blog/unix-timestamp-explained).
  • nbf (não antes): o tempo antes do qual o token não é válido.
  • iat (emitido em): quando o token foi criado.
  • jti (JWT ID): um identificador exclusivo, útil para listas de revogação.

Os pedidos acrescentam as suas próprias reivindicações: scope, roles, tenant_id, email. Mantenha-os poucos, cada reivindicação viaja com cada pedido.

Validar um token corretamente

Um servidor deve verificar todos os seguintes elementos, nesta ordem:

  1. O algoritmo é o que você espera. Configure uma lista de permissões, como ["RS256"]. Nunca deixe o cabeçalho do token decidir livremente; vulnerabilidades históricas permitem que os atacantes mudem para o none ou enganem os servidores para usar uma chave pública como um segredo HMAC.
  2. A assinatura é válida com a chave correta, escolhida pelo kid do seu conjunto de chaves de confiança.
  3. exp está no futuro e nbf está no passado, permitindo uma pequena inclinação do relógio de 3060 segundos.
  4. O iss corresponde exatamente ao seu fornecedor de identidade.
  5. aud contém o identificador do seu serviço, portanto um token emitido para outra API não pode ser reproduzido contra o seu.

Use uma biblioteca mantida jose para JavaScript, PyJWT para Python, golang-jwt para Go em vez de escrever a verificação você mesmo.

Decodificação versus verificação

Decodificação significa Base64URL-decodificação das duas primeiras partes e análise do JSON. Não requer chave e não prova nada sobre autenticidade. É útil para:

  • Debugging por que uma API retorna 401: é aud correto? O token expirou?
  • Verificar quais os escopos ou funções que um fluxo de login realmente concede.
  • Confirmando que uma atualização de token produziu um novo exp.

Verificação significa verificar a assinatura e as alegações, tal como descrito acima. Apenas os servidores devem tomar decisões de autorização, e somente após verificação.

O código front-end pode decodificar um token para mostrar o nome do usuário ou agendar uma atualização antes do exp, mas nunca deve depender de alegações decodificadas para segurança, porque um usuário pode modificar qualquer coisa executada em seu navegador.

Onde armazenar tokens no navegador

Não há uma resposta perfeita, só compromissos:

  • HttpOnly, Secure, SameSite cookies não podem ser lidos pelo JavaScript, que protege contra o roubo de tokens através de scripts cross-site. Eles requerem proteção CSRF, embora SameSite=Lax ou Strict cobre a maioria dos casos.
  • ** Memória ** (uma variável JavaScript) é segura de persistência, mas perdida no recarregamento; combine-a com um token de atualização em um cookie HttpOnly.
  • localStorage é conveniente mas legível por qualquer script na página, então uma única vulnerabilidade XSS vazou todos os tokens.

Para a maioria dos aplicativos da web, tokens de acesso de curta duração na memória mais um token de atualização em um cookie HttpOnly é um bom equilíbrio.

Expirar e revogação

Os JWT são sem estado: um servidor pode validá-los sem uma pesquisa de banco de dados. O outro lado é que um token válido não pode ser facilmente revogado antes de expirar. Mitigantes:

  • Manter os tokens de acesso de curta duração 5 a 15 minutos é comum.
  • Usar tokens de atualização, armazenados de forma segura e verificados em uma base de dados, para emitir novos tokens de acesso.
  • Para ações de alto risco, verifique uma lista de revogação de valores jti ou um carimbo de hora "tokens válidos após" por usuário.

Erros comuns

  • ** Colocando segredos na carga útil. ** As senhas, chaves de API e dados pessoais são lidos por qualquer pessoa com o token. Se você precisar de confidencialidade, use JWE (tokens criptografados) ou mantenha os dados no lado do servidor.
  • ** Tokens muito duradouros.** Um token roubado que é válido por um ano é uma violação de um ano.
  • Salto das verificações de audiência. Sem validação aud, um token para um serviço de baixo privilégio pode ser usado contra um serviço de alto privilégio.
  • Segredos fracos HMAC. Os segredos HS256 devem ser longos e aleatórios no mínimo 256 bits. Segredos curtos podem ser forçados offline a partir de um único token.
  • Logging tokens. Logs de acesso e rastreadores de erros frequentemente capturam cabeçalhos Authorization. Redacte-as.

Inspecionar um token com segurança

Ao depurar, use um decodificador que é executado localmente em seu navegador para que o token nunca seja enviado para terceiros. Prefira tokens expirados ou de ambiente de teste ao compartilhar capturas de tela ou colar em tickets. Verifique:

  • alg e kid no cabeçalho correspondem à configuração do seu provedor.
  • iss e aud correspondem ao que a sua API espera.
  • exp, iat e nbf fazem sentido em relação ao tempo atual.
  • O âmbito e as funções contêm o que a operação requer.

Resumo

Um JWT é um pacote assinado, não criptografado, de reivindicações JSON. A sua segurança vem inteiramente da verificação da assinatura e da validação da reclamação no servidor. A decodificação é inofensiva e útil para depuração; confiar em dados decodificados sem verificação é o risco real. Mantenha os tokens de curta duração, mantenha as cargas úteis pequenas e livres de segredos, valide o algoritmo, assinatura, validade, emissor e público a cada vez, e inspecione os tokens com ferramentas que os mantenham na sua máquina.

Esta página foi traduzida automaticamente do inglês. Se encontrar um erro, avise-nos.

Guias relacionados