Uno degli attacchi HTTP meno noti, ma anche uno dei più subdoli, è l'Open Redirect che viene apportato nei confronti di un'applicazione web per cercare di rubare lo username e la password dell'utente. L'attacco può iniziare con una delle tipiche e-mail di phishing che allarmano l'utente e gli fanno credere che deve autenticarsi al più presto. Ecco qui di seguito un esempio di e-mail che sembra provenire dal customer care di example.com, un dominio su cui potremmo aver pubblicato la nostra applicazione web ASP.NET Core MVC.

La maggior parte degli utenti sa distinguere le e-mail di phishing anche solo osservando il dominio a cui punta il link, che spesso è palesemente diverso da quello legittimo. In questo caso, però, il dominio sembra proprio essere example.com e, senza pensarci troppo, l'utente potrebbe anche decidere di fidarsi e di cliccare il link.

Dopo aver fatto clic, l'utente atterra effettivamente nel sito example.com e inserisce le sue credenziali per accedere. Se il login ha successo, l'applicazione reindirizza l'utente verso il returnUrl indicato in query string, che normalmente viene usato per far tornare l'utente alla pagina di provenienza. Il malintenzionato, però, aveva creato ad arte il returnUrl in modo da causare una ridirezione verso un suo dominio. Infatti, se guardiamo più attentamente il link trovato nell'e-mail di phishing, vediamo che era stato valorizzato con un dominio differente (exxample.com).

Quando l'utente viene reindirizzato verso il dominio del malintenzionato, troverà una pagina di login contraffatta, del tutto simile a quella originale, che cercherà di convincerlo che il suo primo tentativo di accesso non è andato a buon fine.

L'attenzione dell'utente si focalizzerà sull'errore "Invalid login attempt" e così potrebbe non accorgersi di essere stato reindirizzato verso un altro dominio. Pensando di aver sbagliato a inserire la password, proverà di nuovo a ridigitarla, consegnando di fatto le sue credenziali nelle mani del malintenzionato.
L'attacco è definito "Open Redirect" proprio perché alcune applicazioni non fanno alcuna validazione del valore del returnUrl prima di reindirizzare l'utente. Nella nostra applicazione ASP.NET Core MVC dovremmo quindi usare il metodo LocalRedirect dopo un login avvenuto con successo, per ammettere solo redirect a url locali, come mostrato nel prossimo esempio.
[HttpPost] public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl) { if (ModelState.IsValid) { if (await VerificaCredenziali(loginViewModel.Username, loginViewModel.Password)) { //Usiamo LocalRedirect per evitare gli attacchi Open Redirect return LocalRedirect(returnUrl); } } return View(loginViewModel); }
In questo modo, gli attacchi Open Redirect falliscono perché viene sollevata un'eccezione se il returnUrl non è relativo all'applicazione.

In alternativa a LocalRedirect, possiamo anche usare il metodo Url.IsLocalUrl per determinare se l'url è locale oppure no. Nel prossimo esempio vediamo come usarlo per loggare il tentativo di attacco per poi reindirizzare l'utente verso l'homepage.
[HttpPost] public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl, [FromServices] ILoggerFactory loggerFactory) { if (ModelState.IsValid) { if (await VerificaCredenziali(loginViewModel.Username, loginViewModel.Password)) { //Verifichiamo se il returnUrl è locale oppure no if (Url.IsLocalUrl(returnUrl)) { //L'url è locale, quindi possiamo reindirizzare con sicurezza return Redirect(returnUrl); } else { //L'url era esterno all'applicazione, quindi logghiamo l'attacco //e poi reindirizziamo l'utente alla home var logger = loggerFactory.CreateLogger("Login"); logger.LogError($"Tentato un possibile attacco Open Redirect verso {returnUrl}"); return Redirect("~/"); } } } return View(loginViewModel); }
È sempre importante prestare attenzione a questo genere di attacchi sia come sviluppatori che come utenti. Se ci vengono comunicati dei link da fonti non attendibili, la strategia migliore è sempre quella di aprire il browser e recarci noi stessi nel sito in questione, digitando il dominio nella barra degli indirizzi.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Eseguire del codice personalizzato al click di una checkbox in Blazor
Gestire un observable quando la finestra del browser non è attiva in Angular
Implementare logiche di validazione complesse nelle EditForm di Blazor
Realizzare animazioni con Blazor Server
Eseguire integration test di un progetto ASP.NET Core
Kubernetes, gRPC e service mesh
Ricevere notifiche push sull'app con Azure Monitor
Selezione e configurazione degli agent nelle pipeline di Azure DevOps
Recuperare un Azure Storage account cancellato
Keep Calm and Distributed Tracing
Utilizzare le JavaScript Resize Observer API per rispondere ai cambiamenti di dimensione di un oggetto HTML
Impostare l'auto-complete delle pull request in Azure DevOps
I più letti di oggi
- Abilitare il drag&drop delle righe di una tabella in Angular
- Chiamare direttamente un numero di telefono con HTML5
- Creare un radio button per Blazor
- Indicizzare Cosmos DB con Azure Search
- Creare un web server locale con LiveReload
- Modificare la modalità di esecuzione delle query con Include in Entity Framework Core 5