Refresh token: rotação e detecção de reuso

GuiaUNIFOKAL7 min de leituraProduto e integração
Ver em Markdown

Como a rotação de refresh token do RFC 9700 transforma um token roubado em alarme, o que fazer quando o mesmo token volta duas vezes e quando o retry de rede não é ataque.

Neste artigo, 6 seções

O refresh token é a credencial que mantém a pessoa logada por dias sem pedir senha de novo, e por isso vale mais para quem o rouba do que o token de acesso, que vence em minutos. A resposta curta: o RFC 9700, as boas práticas atuais de segurança do OAuth 2.0, exige que o refresh token de cliente público seja preso ao cliente ou rotacionado, e na rotação cada uso devolve um token novo e invalida o anterior, de modo que o token roubado, quando usado, aparece como reuso e derruba a sessão inteira.

  • O RFC 9700, seção 2.2.2, exige refresh token preso ao cliente ou com rotação para cliente público.
  • Na rotação, cada renovação emite um refresh token novo e invalida o anterior, guardando a relação entre eles.
  • Quando um token já usado volta, o servidor não sabe quem é o atacante, e por isso revoga o token ativo da família.
  • O retry de rede legítimo precisa de tratamento próprio para não derrubar a sessão de quem só perdeu a resposta.
  • Troca de senha e logout são eventos em que o RFC permite revogar os refresh tokens automaticamente.

O que o RFC 9700 exige

O RFC 9700, publicado em janeiro de 2025, consolida as boas práticas de segurança do OAuth 2.0. A seção 2.2.2 trata do refresh token em uma frase.

Refresh tokens for public clients MUST be sender-constrained or use refresh token rotation as described in Section 4.14.

RFC 9700, seção 2.2.2

Cliente público é o que não guarda segredo: o aplicativo no celular, a página no navegador. As duas saídas são prender o token a uma chave que só o cliente tem (o token roubado não serve sem a chave) ou rotacioná-lo. A rotação é a que dispensa criptografia no cliente, e é o assunto deste artigo. Para cliente confidencial, o próprio RFC lembra que o OAuth já exige que o refresh token só seja usado pelo cliente para o qual foi emitido.

Como a rotação vira alarme

A seção 4.14.2 do RFC descreve o mecanismo: o servidor emite um refresh token novo a cada renovação, invalida o anterior e "information about the relationship is retained by the authorization server". Essa relação é a família: todos os refresh tokens que descendem do mesmo login.

O roubo aparece assim. O atacante copia o refresh token da pessoa. Daí em diante, um dos dois usa o token primeiro e recebe um novo; o outro, quando tenta, apresenta um token já invalidado. Nas palavras do RFC, o servidor "cannot determine which party submitted the invalid refresh token, but it will revoke the active refresh token". A família inteira cai, o atacante perde o acesso e a pessoa legítima faz login de novo.

o que acontece em cada renovação de uma família de refresh tokens (leitura da casa sobre o RFC 9700, seção 4.14.2)
EventoToken apresentadoResposta do servidor
Renovação normalO token atual da famíliaNovo token de acesso e novo refresh token; o apresentado deixa de valer
ReusoUm token que já foi trocadoRevoga a família inteira e registra evento de segurança
Retry de rede, segundos depoisO mesmo token, antes de o novo ser usadoDevolve de novo a mesma resposta, sem emitir outro token
Token de família revogadaQualquer token daquela famíliaRecusa; a pessoa faz login de novo
Troca de senha ou logoutNenhumRevoga todas as famílias da conta

O custo do mecanismo, o RFC diz com franqueza: a revogação para o ataque "at the cost of forcing the legitimate client to obtain a fresh authorization grant". A pessoa legítima também perde a sessão. É o preço certo: um login a mais em troca de cortar o acesso de quem roubou o token.

Revogar só o token que voltou, e não a família, desfaz a proteção. Se o atacante usou o token primeiro, quem apresenta o token velho é a pessoa legítima; revogar só aquele token deixa o atacante com o token ativo. O RFC manda revogar o token ativo, e a forma prática é derrubar a família.

O retry que não é ataque

O ponto fraco da rotação está na rede. O aplicativo pede a renovação, o servidor emite o token novo e invalida o antigo, e a resposta se perde no caminho. O aplicativo tenta de novo com o token antigo, que agora é um token já usado. Sem tratamento, uma conexão ruim no metrô derruba a sessão como se fosse roubo.

A saída é tornar a renovação idempotente por uma janela curta: se o mesmo token volta em poucos segundos e o token novo ainda não foi usado, o servidor devolve a mesma resposta, sem emitir um terceiro token. Fora da janela, ou se o token novo já foi usado, é reuso. O detalhe que importa é não emitir um filho novo dentro da janela, porque dois filhos válidos são dois ramos na família, e o atacante que acertar a janela ganha um ramo próprio. A mesma lógica de resposta idempotente aparece em idempotência em APIs.

Validade e revogação

A rotação não substitui a validade. A seção 4.14.2 do RFC 9700 recomenda que o refresh token expire quando o cliente fica inativo por um tempo, e permite revogação automática em evento de segurança, citando a troca de senha e o logout. Duas validades organizam a família: a de inatividade, que encerra a sessão esquecida, e a absoluta, que obriga um novo login mesmo com uso contínuo. A NIST SP 800-63B-4 dá a referência para a absoluta: reautenticação em até 30 dias no nível 1 de garantia.

O token de acesso fica curto, em minutos, porque não há como revogá-lo sem consulta ao emissor: a sua API o valida localmente, como mostra o artigo sobre o que validar num JWT de acesso. O refresh token é o ponto de controle: é nele que a revogação acontece, e é por ele que o acesso para em minutos depois de uma família cair.

Perguntas frequentes

Rotação de refresh token é obrigatória?

Para cliente público, o RFC 9700, seção 2.2.2, exige rotação ou refresh token preso ao cliente por criptografia. Para cliente confidencial, o OAuth já exige que o token só seja usado pelo cliente para o qual foi emitido.

O que fazer quando um refresh token já usado volta?

Tratar como reuso e revogar a família inteira daquele login. O RFC 9700 explica que o servidor não sabe se quem apresentou o token velho é o atacante ou a pessoa, e por isso revoga o token ativo.

A rotação derruba a sessão quando a rede falha?

Não precisa derrubar. Com uma janela curta de idempotência, o mesmo token que volta em segundos, antes de o novo ser usado, recebe a mesma resposta, sem emitir um token novo.

Quanto tempo deve durar um refresh token?

O RFC 9700 deixa a validade a critério do servidor e recomenda expirar por inatividade. A NIST SP 800-63B-4 recomenda reautenticação em até 30 dias no nível 1, o que serve de teto para a validade absoluta.

Fontes citadas

  • RFC 9700, Best Current Practice for OAuth 2.0 Security, seções 2.2.2 e 4.14, em rfc-editor.org
  • RFC 6749, The OAuth 2.0 Authorization Framework, em rfc-editor.org
  • NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management, seção 2 (reautenticação), em pages.nist.gov