fix: bloqueia open-redirect via next=/\evil.com no login

_proximo_seguro() (app/routers/auth.py) so recusava next que comecasse
com "//", mas navegadores modernos tratam "/\" como equivalente a
"//" (URL protocol-relative), entao next=/\evil.com ainda era um open
redirect explorável via link de login malicioso.

Bloqueia tambem o prefixo "/\".

Teste de regressao em tests/test_router_auth.py: POST /login com
next=/\evil.com precisa redirecionar para /clientes, nao para o host
externo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Gustavo
2026-08-13 21:18:46 -03:00
co-authored by Claude Sonnet 5
parent aa1c528197
commit ba8ffaede7
2 changed files with 12 additions and 1 deletions
+11
View File
@@ -56,6 +56,17 @@ def test_post_login_next_externo_e_ignorado_por_seguranca():
assert resposta.headers["location"] == "/clientes"
def test_post_login_next_com_barra_invertida_e_ignorado_por_seguranca():
# "/\evil.com" é tratado por navegadores modernos como equivalente a
# "//evil.com" (URL protocol-relative) — precisa ser bloqueado também.
resposta = client.post(
"/login",
data={"usuario": "admin", "senha": "teste123", "next": "/\\evil.com", "csrf_token": CSRF_TESTE},
)
assert resposta.status_code == 303
assert resposta.headers["location"] == "/clientes"
def test_post_login_credenciais_erradas_nao_grava_cookie():
resposta = client.post(
"/login", data={"usuario": "admin", "senha": "errada", "csrf_token": CSRF_TESTE}