Un open redirect è una vulnerabilità applicativa in cui un endpoint accetta un URL come parametro e reindirizza l’utente verso di esso senza verificare che la destinazione sia attendibile. L’attaccante costruisce un link al sito legittimo che, una volta cliccato, trasporta la vittima su un sito malevolo — con il dominio fidato visibile nella barra degli indirizzi al momento del clic.
Meccanismo
Il pattern vulnerabile tipico:
https://banca.it/login?next=https://evil.it/fake-login
Il server, dopo il login, legge il parametro next e reindirizza l’utente senza validazione:
# Codice vulnerabile
next_url = request.args.get('next')
return redirect(next_url)
Il link inviato alla vittima inizia con https://banca.it/ — il dominio appare nella email, nel testo del link hover, nei filtri antispam — e per questo supera i controlli di reputazione. Solo dopo l’autenticazione l’utente si ritrova su evil.it.
Utilizzo negli attacchi
Phishing: l’open redirect trasforma un link malevolo in uno apparentemente legittimo, aumentando drasticamente il tasso di successo di campagne di phishing. È particolarmente efficace quando il dominio bersaglio è una banca, un servizio email o un provider di identità.
Aggiramento di filtri URL: i sistemi di reputazione URL (es. protezioni email aziendali, link scanner) vedono il dominio legittimo e non bloccano il link.
OAuth token theft: negli flussi OAuth 2.0, se il server di autorizzazione accetta redirect_uri non esattamente corrispondenti alla registrazione, un open redirect nell’applicazione client può essere combinato per far atterrare il codice di autorizzazione su un server controllato dall’attaccante.
Bypass di referrer check: alcune applicazioni usano l’header Referer per validare l’origine di una richiesta. Un redirect da dominio legittimo a sito malevolo porta un Referer pulito.
Varianti di bypass della validazione
Quando il server tenta di validare il parametro in modo semplice, esistono numerose tecniche di bypass:
# Slash doppi (protocollo-relativo)
//evil.it/pagina
# Backslash (interpretato come slash da alcuni browser)
https://banca.it\@evil.it
# Encoding URL
https://evil%2Eit/
# Redirect con frammento
https://banca.it/?next=https://evil.it%23.banca.it
# Subdomain confuso
https://banca.it.evil.it/
# Newline injection (CRLF) per header injection
https://banca.it/?next=%0d%0aLocation:%20https://evil.it
Contromisure
Lista bianca delle destinazioni: il metodo più sicuro. Il parametro next viene confrontato con una lista esplicita di URL o path consentiti:
ALLOWED_REDIRECTS = ['/dashboard', '/profilo', '/impostazioni']
def safe_redirect(next_url):
if next_url in ALLOWED_REDIRECTS:
return redirect(next_url)
return redirect('/')
Solo path relativi: non accettare URL assoluti nel parametro di redirect — solo path (/dashboard) che per definizione restano sullo stesso host.
Validazione dell’host: se servono redirect assoluti, estrarre e verificare che l’host corrisponda al dominio applicativo:
from urllib.parse import urlparse
def is_safe_redirect(url, host):
parsed = urlparse(url)
return parsed.netloc == '' or parsed.netloc == host
Firma del parametro: in contesti critici, firmare crittograficamente il valore del parametro next alla generazione e verificare la firma alla restituzione — impedisce la manipolazione lato client.
Relazione con altri argomenti
- Phishing — uso principale degli open redirect in campagne di phishing.
- SSRF — anche SSRF sfrutta URL non validati, ma verso destinazioni interne anziché esterne.
- OWASP Top 10 — rientra in A01 Broken Access Control e A05 Security Misconfiguration a seconda del contesto.