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
Utilizzare il nuovo modello GPT-4o con Azure OpenAI
Creare una custom property in GitHub
Conoscere il rendering Server o WebAssembly a runtime in Blazor
Selettore CSS :has() e i suoi casi d'uso avanzati
Autenticazione di git tramite Microsoft Entra ID in Azure DevOps
Bloccare l'esecuzione di un pod in mancanza di un'artifact attestation di GitHub
Utilizzare l nesting nativo dei CSS
Garantire la provenienza e l'integrità degli artefatti prodotti su GitHub
Sfruttare GPT-4o realtime su Azure Open AI per conversazioni vocali
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
Cancellare una run di un workflow di GitHub
I più letti di oggi
- Organizzare i moduli sfruttando CommonJS in Javascript
- Proteggere le risorse Azure con private link e private endpoints
- Rinnovare il token di una GitHub App durante l'esecuzione di un workflow
- Utilizzare le local static function di C# 8
- Real Code Day - Firenze
- WPC 2011 - Assago (MI)
- Disponibile il codice sorgente di Moonlight
- ADO.NET Data Services Silverlight 2 Beta2 Client library Refresh
- Rilasciata la versione beta dei Windows Phone 7 Developer Tools
- WinPhoneItalia.com: dal 15 settembre tutto per sviluppare per Windows Phone e mobile