Melhores Práticas para Proteger OAuth em Aplicações Web

O OAuth 2.0 tornou-se o padrão para autenticação de APIs, mas implementá-lo de forma segura continua sendo um desafio. Com roubo de tokens, fluxos obsoletos e vulnerabilidades específicas de navegadores ameaçando aplicações web diariamente, os desenvolvedores precisam de orientações claras sobre o que realmente funciona. Este artigo aborda as práticas essenciais de segurança do OAuth 2.0 que você precisa em 2025, desde os requisitos da RFC 9700 até padrões específicos para SPAs.
Principais Conclusões
- Nunca armazene tokens OAuth em localStorage ou sessionStorage—use armazenamento em memória para SPAs
- Authorization Code Flow com PKCE é obrigatório para todos os clientes sob OAuth 2.1
- Implemente rotação de refresh tokens e access tokens de curta duração (15-30 minutos)
- Considere o padrão Backend for Frontend (BFF) para manter tokens completamente fora do navegador
Por Que a Segurança OAuth Importa Mais do Que Nunca
OAuth protege os dados dos seus usuários eliminando o compartilhamento de senhas entre aplicações. Em vez de fornecer suas credenciais a aplicativos de terceiros (como entregar as chaves da sua casa), o OAuth emite tokens temporários e com escopo definido—mais como dar uma chave de manobrista que apenas liga o carro.
Mas aqui está o problema: tokens são alvos valiosos. Um access token roubado concede acesso imediato à API. Escolhas ruins de implementação—armazenar tokens em localStorage, usar fluxos obsoletos ou pular o PKCE—transformam vulnerabilidades menores em violações graves.
Principais Riscos de Segurança e Como Evitá-los
Roubo e Armazenamento de Tokens
O que não fazer: Armazenar tokens em localStorage ou sessionStorage. Qualquer ataque XSS pode ler esses valores e exfiltrá-los para servidores controlados por atacantes.
O que fazer: Para SPAs, mantenha tokens apenas em memória. Para aplicações server-side, armazene-os em sessões criptografadas no servidor. Use access tokens de curta duração (15-30 minutos) para limitar danos causados por qualquer roubo.
Fluxos Obsoletos a Evitar
O Implicit Flow está morto. Tanto a RFC 9700 quanto o OAuth 2.1 o proíbem. Por quê? Porque ele envia tokens diretamente em fragmentos de URL, expondo-os ao histórico do navegador, cabeçalhos referrer e qualquer JavaScript na página.
O fluxo Resource Owner Password Credentials também deve ser evitado—ele derrota todo o propósito do OAuth ao exigir que aplicações manipulem senhas de usuários diretamente.
Sempre use: Authorization Code Flow com PKCE para todos os clientes, incluindo SPAs e aplicativos móveis.
Discover how at OpenReplay.com.
Padrões Modernos: RFC 9700 e OAuth 2.1
PKCE Agora É Obrigatório
PKCE (Proof Key for Code Exchange) previne ataques de interceptação de código de autorização. Veja como funciona:
// Generate code verifier and challenge
const verifier = generateRandomString(128);
const challenge = base64url(sha256(verifier));
// Include challenge in authorization request
const authUrl = `https://auth.example.com/authorize?` +
`client_id=app123&` +
`code_challenge=${challenge}&` +
`code_challenge_method=S256`;
// Send verifier when exchanging code for token
const tokenResponse = await fetch('/token', {
method: 'POST',
body: JSON.stringify({
code: authorizationCode,
code_verifier: verifier
})
});
O OAuth 2.1 torna o PKCE obrigatório para todos os fluxos de código de autorização, não apenas para clientes públicos.
Vinculação de Token com mTLS ou DPoP
A vinculação de token garante que tokens roubados não possam ser usados por atacantes. Duas abordagens principais:
- mTLS (Mutual TLS): Vincula tokens a certificados de cliente
- DPoP (Demonstrating Proof of Possession): Usa prova criptográfica sem certificados
Ambos previnem ataques de replay de token ao vincular criptograficamente tokens ao cliente legítimo.
Rotação de Refresh Token
Nunca reutilize refresh tokens. Cada atualização deve emitir um novo refresh token e invalidar o antigo. Isso limita a janela de abuso de refresh tokens roubados:
// Server-side refresh token handling
async function refreshAccessToken(oldRefreshToken) {
// Validate and revoke old refresh token
await revokeToken(oldRefreshToken);
// Issue new token pair
return {
access_token: generateAccessToken(),
refresh_token: generateRefreshToken(), // New refresh token
expires_in: 1800
};
}
Segurança OAuth em SPAs: Considerações Especiais
Aplicações de página única enfrentam desafios únicos, pois todo o código é executado no navegador. O navegador é território hostil—assuma que qualquer dado ali pode ser comprometido.
Padrão Backend for Frontend (BFF)
A abordagem mais segura mantém tokens completamente fora do navegador. Um backend proxy leve gerencia os fluxos OAuth e mantém tokens no servidor, usando cookies seguros, httpOnly e sameSite para a sessão do SPA.
Padrão Token Handler
Para equipes que desejam os benefícios de SPAs sem complexidade de backend, o padrão Token Handler oferece um meio-termo. Ele usa um proxy especializado que:
- Gerencia fluxos OAuth
- Armazena tokens com segurança
- Emite cookies de sessão de curta duração para o SPA
- Traduz requisições autenticadas por cookie em chamadas de API autenticadas por token
Se Você Precisar Armazenar Tokens no Navegador
Quando BFF não for viável:
- Armazene tokens apenas em memória, nunca em localStorage
- Use service workers para isolar o acesso ao token
- Implemente expiração agressiva de tokens (5-15 minutos)
- Nunca armazene refresh tokens no navegador
Checklist de Implementação
✓ Use Authorization Code Flow com PKCE para todos os clientes
✓ Implemente correspondência exata de URI de redirecionamento
✓ Defina tempos de vida de token para durações mínimas viáveis
✓ Habilite rotação de refresh token para clientes públicos
✓ Use parâmetro state para proteção CSRF
✓ Implemente vinculação de token (mTLS/DPoP) para aplicações de alta segurança
✓ Para SPAs: Considere padrões BFF ou Token Handler
✓ Monitore requisitos de conformidade com OAuth 2.1
Conclusão
Proteger OAuth em aplicações web requer entender tanto os pontos fortes do protocolo quanto as ameaças específicas enfrentadas pela sua arquitetura. Comece com os requisitos da RFC 9700: PKCE obrigatório, sem implicit flow e manipulação adequada de tokens. Para SPAs, considere seriamente manter tokens completamente fora do navegador através dos padrões BFF ou Token Handler. Estas não são apenas melhores práticas—são o padrão mínimo para segurança OAuth em 2025.
Perguntas Frequentes
Não. Mesmo aplicações sem dados sensíveis não devem usar localStorage para tokens. Tokens roubados podem ser usados para sequestro de conta, abuso de API e como trampolins para ataques mais sérios. Sempre armazene tokens em memória ou use sessões server-side.
Sim. OAuth 2.1 torna PKCE obrigatório para todos os fluxos de código de autorização, incluindo clientes confidenciais. PKCE adiciona defesa em profundidade contra ataques de interceptação de código de autorização que client secrets sozinhos não podem prevenir, especialmente em cenários envolvendo redes comprometidas ou extensões de navegador maliciosas.
Use o padrão Backend for Frontend onde seu backend gerencia refresh tokens e fornece ao SPA access tokens de curta duração via cookies seguros. Alternativamente, use autenticação silenciosa com prompt=none para obter novos tokens sem interação do usuário quando o access token expirar.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.