Glossário

O que é session fixation — fazer a vítima logar com um ID que o invasor já conhece

Session fixation faz a vítima logar com um ID de sessão plantado pelo invasor. A defesa: regenerar o ID no login e não aceitar IDs vindos da URL.

Publicado 2026-06-11 Atualizado 2026-10-06 7 min de leitura
Nesta página

Session fixation é quando a vítima loga com um ID que o invasor preparou. Veja como funciona e como evitá-lo de forma confiável (sem passos de ataque).

Por que funciona

A causa é um design em que o ID de sessão não muda ao longo do login. Se ele não muda, um ID que o invasor conhecia antes do login ainda funciona como "autenticado" depois do login.

1) O invasor faz a vítima usar um ID de sessão conhecido (via um link, etc.)
↓ a vítima loga com esse ID ainda definido
2) O ID não é regenerado = o mesmo ID torna-se "autenticado"
↓ o invasor conhecia esse ID o tempo todo
3) Acessar com o mesmo ID = passar-se pela vítima
Se o ID não muda no login, um ID que o invasor conhecia de antemão torna-se autenticado como está.

Pode se combinar com CSRF ou XSS, mas a essência da fixation em si é uma única coisa: o ID não foi regenerado no login.

O guia "How to Secure Your Website" da IPA (Agência de Promoção de Tecnologia da Informação do Japão) trata isso como uma forma de gerenciamento de sessão inadequado e diz que todo site com função de login precisa ficar atento. A correção fundamental indicada é iniciar uma nova sessão após o login bem-sucedido.

Fixation vs. sequestro de sessão vs. CSRF

Esses três são fáceis de confundir. Todos abusam de um estado logado, mas diferem no que o invasor tem e em qual defesa funciona.

ItemSession fixationSequestro de sessãoCSRF
O que o invasor temUm ID que ele preparou (conhecido desde o início)Um ID já emitido e roubadoNenhum ID
O que acontece com a vítimaEla loga com o ID plantadoO ID emitido dela é roubadoEla é levada a enviar uma requisição não intencional
Defesa principalRegenerar o ID no loginHttpOnly/Secure, prevenção de XSS, vidas curtasTokens CSRF, SameSite

A fixation é a que um único passo, regenerar o ID no login, corrige na raiz.

Defesa: regenere o ID no login

1

Regenere o ID de sessão no login bem-sucedido (o mais importante)

No instante em que a autenticação tem sucesso, descarte o ID antigo e emita um novo ID de sessão (o session regenerate/renew da maioria dos frameworks). Qualquer ID pré-plantado é invalidado imediatamente. Regenere também na escalada de privilégio (por exemplo, virar admin).
2

Não aceite IDs de sessão pela URL

Trate o ID de sessão em um cookie e ignore um ID especificado em um parâmetro da URL. Feche o caminho que o invasor usa para fazer a vítima adotar um ID 'fixado'.
3

Defina as flags de cookie

Defina os cookies de sessão como HttpOnly (o JS não pode ler), Secure (só HTTPS) e SameSite (restringe o envio entre sites). Enfraquece em conjunto os caminhos de sequestro relacionados.
4

Expire sessões com bom senso

Expire por timeout de inatividade, logout e troca de senha para que um ID fixado não continue válido indefinidamente.

O OWASP Session Management Cheat Sheet recomenda regenerar o ID a cada mudança de privilégio e usar um mecanismo "estrito", que só aceita IDs gerados pelo próprio servidor. Um mecanismo "permissivo", que adota um ID desconhecido trazido de fora, deixa espaço para que um ID escolhido pelo invasor seja aceito.

O que frameworks comuns fazem por padrão

A maioria dos frameworks regenera o ID automaticamente se você usa o login padrão deles. O risco aparece quando você escreve o login por conta própria ou desliga a proteção padrão.

AmbienteComportamento padrãoO que verificar se você escreve por conta própria
PHP (sessões puras)Não regenera sozinho; session.use_strict_mode tem padrão 0Chamar session_regenerate_id(true) no login bem-sucedido; definir use_strict_mode como 1
LaravelRegenerado automaticamente na autenticação quando você usa um starter kit ou o FortifySe escrever o login à mão, chamar $request->session()->regenerate()
Spring SecurityAtivado por padrão (changeSessionId no Servlet 3.1+)Garantir que ninguém definiu sessionFixation().none()

No PHP, as configurações que passam IDs de sessão em URLs (ativar session.use_trans_sid, desativar session.use_only_cookies) foram descontinuadas no PHP 8.4. Se você carrega um arquivo de configuração antigo, revise-as.

Como verificar o seu próprio site

Em um site que você administra, verifique estas quatro coisas. As ferramentas de desenvolvedor bastam.

  1. Nas ferramentas de desenvolvedor, em "Application" (no Firefox, "Armazenamento"), anote o valor do cookie de sessão e olhe de novo depois de logar. Se não mudou, o ID não é regenerado no login
  2. Confira que a página de login e as URLs após o login não carregam um ID de sessão como PHPSESSID= ou ;jsessionid=
  3. No mesmo painel, confira que o cookie de sessão tem HttpOnly, Secure e SameSite
  4. Depois de sair, coloque de volta o valor antigo do cookie e recarregue; confirme que você não volta a estar logado

Os atributos de cookie também são cobertos pela auditoria de segurança do site, que verifica sites cuja propriedade você confirmou. Colocar a verificação 1 num teste automatizado sempre que mexer no fluxo de login faz você perceber na hora se a regeneração sumir.

A visão deste site: não desabilite o 'regenerate' do framework

A session fixation é quase totalmente evitada por um único passo: regenerar o ID no login, e não por código personalizado elaborado. A chave é não desabilitar acidentalmente nem esquecer de chamar o mecanismo que seu framework já fornece. Usar os padrões seguros de uma implementação comprovada supera fazer seu próprio gerenciamento de sessão. Neste site mantemos "não construa autenticação/manuseio de chaves você mesmo; não desabilite os padrões seguros". Como no IDOR, a autenticação/autorização deve ser imposta por um mecanismo em cada requisição.

Fontes (primárias)

  • IPA, "How to Secure Your Website", 1.4 Gerenciamento de sessão inadequado — ipa.go.jp (em japonês; iniciar nova sessão após o login; não colocar IDs em URLs)
  • OWASP Session Management Cheat Sheet — cheatsheetseries.owasp.org (em inglês; regeneração na mudança de privilégio, mecanismo estrito, atributos de cookie)
  • MITRE CWE-384: Session Fixation — cwe.mitre.org (em inglês)
  • PHP Manual, "Runtime Configuration" (sessões) — php.net (em inglês; padrões como use_strict_mode; descontinuações do 8.4)
  • Documentação do Laravel, "HTTP Session" — laravel.com / Spring Security, "Authentication Persistence and Session Management" — docs.spring.io (em inglês)

Leia a seguir

Classificação

O CWE classifica os tipos de fraqueza por trás das vulnerabilidades; o MITRE ATT&CK classifica as técnicas dos atacantes. Ambos são mantidos pela MITRE e amplamente usados para rotular vulnerabilidades e regras de detecção.

CWE (tipo de fraqueza)

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QComo a fixation difere do sequestro de sessão?
A

O sequestro rouba o ID de sessão já emitido de alguém. A fixation é o inverso: o invasor faz a vítima usar um ID que o invasor já conhece, e então espera que a vítima logue com ele. Não rouba; faz com que um ID conhecido pelo invasor seja autenticado.

QQual é a principal defesa?
A

Regenerar o ID de sessão no momento do login. A maioria dos frameworks/bibliotecas de sessão tem isso (session regenerate/renew): ao autenticar com sucesso, descarte o ID antigo e emita um novo. Só isso já invalida qualquer ID que o invasor tenha plantado de antemão. Regenere também em mudanças de privilégio (por exemplo, virar admin).

QPor que colocar um ID de sessão na URL é perigoso?
A

Um ID na URL vaza facilmente por links compartilhados, pelo cabeçalho Referer, por logs e pelo histórico do navegador, o que dá ao invasor uma forma de fazer a vítima usar um ID 'fixado'. Trate os IDs de sessão em cookies, não em parâmetros da URL, e não aceite um ID especificado pela URL.

QComo verifico se o meu site é vulnerável a session fixation?
A

No seu próprio site, abra as ferramentas de desenvolvedor do navegador e compare o valor do cookie de sessão antes e depois de fazer login. Se o valor for o mesmo depois do login, o ID não está sendo regenerado e você precisa corrigir. Confira também que nenhum ID de sessão aparece na URL e que o cookie tem HttpOnly, Secure e SameSite definidos.

QQuais configurações do PHP previnem session fixation?
A

Chame session_regenerate_id(true) no login bem-sucedido para trocar para um novo ID. No php.ini, defina session.use_strict_mode como 1 para que o servidor rejeite IDs que ele não emitiu (o padrão é 0). Mantenha session.use_only_cookies no padrão 1 e session.use_trans_sid no padrão 0 para que os IDs nunca sejam passados em URLs.

QSe eu uso JWT, a session fixation ainda pode acontecer?
A

Se você não usa um ID de sessão no servidor e emite um token novo no login bem-sucedido, o ataque de 'fazer um ID escolhido de antemão ser autenticado' é difícil de realizar. Mas, se um token emitido antes do login continuar sendo usado depois dele, o mesmo problema pode ocorrer. Seja qual for o mecanismo, a regra é emitir um identificador novo no momento do login.