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
Gestire la cancellazione di una richiesta in streaming da Blazor
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Miglioramenti agli screen reader e al contrasto in Angular
Ottenere un token di accesso per una GitHub App
Sfruttare GPT-4o realtime su Azure Open AI per conversazioni vocali
Limitare le richieste lato server con l'interactive routing di Blazor 8
Generare un hash con SHA-3 in .NET
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Change tracking e composition in Entity Framework
Sviluppare un'interfaccia utente in React con Tailwind CSS e Preline UI
Creare una libreria CSS universale: Clip-path