flawopen.com/Vulnerabilities/Fixação de sessão e proteção de cookies
Fixação de sessão: troque o ID no login (CWE-384)
Imagine que alguém convence um viajante a usar um número de ficha de bagagem que o atacante já conhece. Se a companhia aérea mantiver esse número após o check-in, o atacante poderá retirar a mala. Na fixação de sessão, a aplicação aceita um identificador que o atacante consegue fazer a vítima usar e depois o transforma em uma sessão autenticada sem trocá-lo. As duas condições são necessárias; um link de phishing sozinho não fixa a sessão, a menos que a aplicação aceite ou permita definir esse identificador.
Conceitos centrais e termos do subsistema
- Fixação de sessão
- Falha de gerenciamento de sessão em que a aplicação aceita um identificador conhecido pelo atacante e o mantém quando a vítima se autentica.
- Rotação do ID de sessão
- Emita um identificador novo e imprevisível quando a autenticação elevar os privilégios da sessão. Preserve somente os dados de sessão que a aplicação pretende manter.
- Atributos de cookie
Securerestringe o envio do cookie a HTTPS;HttpOnlyimpede acesso ao cookie por JavaScript;SameSitecontrola parte do envio em contextos cross-site. São proteções distintas e não substituem a rotação do ID.- Prefixo
__Host- - Em navegadores compatíveis, exige cookie Secure criado por HTTPS, com
Path=/e sem atributoDomain. Ajuda a impedir que um subdomínio irmão defina um cookie para o domínio pai com o mesmo nome.
Fluxo de ataque passo a passo
O atacante obtém ou escolhe um identificador de sessão
Uma falha ou funcionalidade separada permite que o atacante obtenha um ID e faça o navegador da vítima enviá-lo. O método depende da aplicação; um link comum de phishing não funciona se IDs de sessão na URL não forem aceitos.
A vítima usa o identificador conhecido pelo atacante
O navegador envia esse ID à aplicação, que o trata como uma sessão anônima válida. O atacante precisa conseguir reconhecer ou reutilizar o mesmo identificador.
A autenticação eleva os privilégios da sessão
A vítima entra na conta. Se a aplicação associar a identidade autenticada ao ID existente sem trocá-lo, esse identificador conhecido passa a apontar para a sessão autenticada.
O atacante reutiliza o identificador inalterado
Se o atacante ainda puder enviar o ID e o servidor não o tiver invalidado, poderá acessar a sessão da vítima. A rotação do ID durante a mudança de privilégio interrompe essa cadeia.
Mecanismo e causa raiz
A fixação de sessão exige tanto a influência do atacante sobre o identificador usado pela vítima quanto a falha da aplicação em substituí-lo após o login. Atributos de cookie são defesa em profundidade, mas nenhum substitui a rotação: HttpOnly limita a leitura por scripts, Secure restringe o transporte a HTTPS, SameSite reduz alguns envios cross-site e __Host- limita o escopo do cookie em navegadores compatíveis.
# VULNERABLE: custom session code keeps the pre-authentication ID.
def login_view(request):
user = authenticate(request, request.POST["username"],
request.POST["password"])
if user is not None:
# BUG: privilege changes, but the session ID does not.
request.session["user_id"] = user.pk
request.session["authenticated"] = True
return redirect("/account/")
return redirect("/login/")
# HARDENED: Django login() rotates the session key on authentication.
from django.contrib.auth import authenticate, login
def login_view(request):
user = authenticate(request, request.POST["username"],
request.POST["password"])
if user is not None:
# Uses Django's supported authentication/session integration.
login(request, user)
return redirect("/account/")
return redirect("/login/")
# settings.py: use HTTPS, host-only scope, and a deliberate SameSite policy.
SESSION_COOKIE_NAME = "__Host-sessionid"
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_PATH = "/"
SESSION_COOKIE_DOMAIN = None
Sequência de ataque e exemplo conceitual
- 1Pré-condição: Uma falha ou funcionalidade separada permite que o atacante influencie o ID que o navegador da vítima enviará.
- 2ID conhecido: O atacante consegue reconhecer ou reutilizar o mesmo ID de sessão anônimo.
- 3Autenticação: A vítima entra na conta enquanto o navegador continua enviando o ID conhecido.
- 4Sem rotação: A aplicação promove a sessão existente em vez de substituir seu identificador.
- 5Impacto condicional: O atacante só acessa a sessão autenticada enquanto o ID conhecido continuar válido e utilizável.
Regras de prevenção e proteção para engenharia
- ✓Troque o ID ao elevar privilégios: Gere um ID imprevisível no login e em outras elevações de privilégio; invalide o ID anterior conforme o comportamento documentado do framework.
- ✓Use APIs de autenticação do framework: Prefira a integração oficial de login e sessão (no Django,
django.contrib.auth.login()) a inserir manualmente a identidade na sessão. - ✓Rejeite IDs controlados pelo atacante: Não aceite IDs de sessão em URLs. Impeça injeção de cookies por subdomínios irmãos e teste qualquer lógica personalizada de sessão/cookie.
- ✓Configure atributos para suas funções reais: Use
SecureeHttpOnly; considere o prefixo__Host-comPath=/e semDomain. EscolhaSameSite=LaxouStrictconforme os fluxos legítimos de login cross-site; SameSite não substitui tokens CSRF quando necessários. - ✓Teste a transição: Em um teste automatizado, registre o ID anônimo, autentique, confirme que o ID mudou e verifique que o ID antigo não acessa a sessão autenticada.