ASP.NET - Vulnerabilidade - Open Redirection Attacks
Autor: Matheus Veras | Publicado: 2011-01-24T05:26:00-08:00



O que é?
Qualquer aplicação web que redireciona para uma URL que é especificado através do&nbsp;request, tais como os dados querystring ou de forma potencialmente podem ser alterados&nbsp;para redirecionar os usuários para um URL maliciosa.&nbsp;Esta violação é&nbsp;chamado um ataque de redirecionamento aberto (Open Redirection Attacks).
Como evitar?&nbsp;
Protegendo&nbsp;Aplicações&nbsp;ASP.NET MVC&nbsp;1.0 e&nbsp;MVC&nbsp;2&nbsp;

Podemos promover&nbsp;três&nbsp;mudanças em&nbsp;nossos&nbsp;aplicativos&nbsp;existentes em&nbsp;ASP.NET MVC&nbsp;1.0 e&nbsp;2, incluindo&nbsp;o&nbsp;IsLocalUrl&nbsp;método&nbsp;auxiliar&nbsp;()&nbsp;e&nbsp;alterar o evento&nbsp;LogOn&nbsp;para validar o parâmetro&nbsp;ReturnUrl.
O&nbsp;IsLocalUrl&nbsp;()&nbsp;método&nbsp;da&nbsp;classe&nbsp;3&nbsp;ASP.NET MVC&nbsp;UrlHelper
public bool IsLocalUrl(string url) {
&nbsp; &nbsp; return System.Web.WebPages.RequestExtensions.IsUrlLocalToHost(
&nbsp; &nbsp; &nbsp; &nbsp; RequestContext.HttpContext.Request, url);
}
IsUrlLocalToHost&nbsp;()&nbsp;método&nbsp;da&nbsp;classe&nbsp;requestExtensions&nbsp;System.Web.WebPages

public static bool IsUrlLocalToHost(this HttpRequestBase request, string url) {
&nbsp; &nbsp; if (url.IsEmpty()) {
&nbsp; &nbsp; &nbsp; &nbsp; return false;
&nbsp; &nbsp; }
&nbsp;
&nbsp; &nbsp; Uri absoluteUri;
&nbsp; &nbsp; if (Uri.TryCreate(url, UriKind.Absolute, out absoluteUri)) {
&nbsp; &nbsp; &nbsp; &nbsp; return String.Equals(request.Url.Host, absoluteUri.Host, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringComparison.OrdinalIgnoreCase);
&nbsp; &nbsp; }
&nbsp; &nbsp; else {
&nbsp; &nbsp; &nbsp; &nbsp; bool isLocal = !url.StartsWith("http:", StringComparison.OrdinalIgnoreCase)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; !url.StartsWith("https:", StringComparison.OrdinalIgnoreCase)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; Uri.IsWellFormedUriString(url, UriKind.Relative);
&nbsp; &nbsp; &nbsp; &nbsp; return isLocal;
&nbsp; &nbsp; }
}
Vamos&nbsp;adicionar&nbsp;o&nbsp;IsLocalUrl&nbsp;() para&nbsp;o&nbsp;AccountController,&nbsp;mas&nbsp;você&nbsp;é&nbsp;encorajado a&nbsp;adicionar&nbsp;em&nbsp;uma&nbsp;classe&nbsp;auxiliar&nbsp;separada, se possível.&nbsp;Nós vamos&nbsp;fazer&nbsp;duas&nbsp;pequenas alterações no&nbsp;ASP.NET MVC&nbsp;versão 3&nbsp;do&nbsp;IsLocalUrl&nbsp;() para&nbsp;que&nbsp;ele&nbsp;irá&nbsp;trabalhar por dentro da&nbsp;AccountController.

IsLocalUrl&nbsp;()&nbsp;método, que foi&nbsp;modificado para&nbsp;uso&nbsp;com&nbsp;uma&nbsp;classe&nbsp;Controller&nbsp;MVC

//Note: This has been copied from the System.Web.WebPages RequestExtensions class
private bool IsLocalUrl(string url)
{
&nbsp; &nbsp; if (string.IsNullOrEmpty(url))
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; return false;
&nbsp; &nbsp; }
&nbsp;
&nbsp; &nbsp; Uri absoluteUri;
&nbsp; &nbsp; if (Uri.TryCreate(url, UriKind.Absolute, out absoluteUri))
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; return String.Equals(this.Request.Url.Host, absoluteUri.Host, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringComparison.OrdinalIgnoreCase);
&nbsp; &nbsp; }
&nbsp; &nbsp; else
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; bool isLocal = !url.StartsWith("http:", StringComparison.OrdinalIgnoreCase)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; !url.StartsWith("https:", StringComparison.OrdinalIgnoreCase)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; Uri.IsWellFormedUriString(url, UriKind.Relative);
&nbsp; &nbsp; &nbsp; &nbsp; return isLocal;
&nbsp; &nbsp; }
}
Agora podemos chamar nossa ação LogOn para validar o parâmetro ReturnUrl, como mostrado no código a seguir.
Atualizado&nbsp;Método de Logon&nbsp;que&nbsp;valida&nbsp;o parâmetro&nbsp;ReturnUrl

[HttpPost] public ActionResult LogOn(LogOnModel model, string returnUrl) { 
&nbsp; &nbsp; if (ModelState.IsValid) 
&nbsp; &nbsp; { 
&nbsp; &nbsp; &nbsp; &nbsp; if (MembershipService.ValidateUser(model.UserName, model.Password)) 
&nbsp; &nbsp; &nbsp; &nbsp; { 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FormsService.SignIn(model.UserName, model.RememberMe); 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (IsLocalUrl(returnUrl)) 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Redirect(returnUrl); 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return RedirectToAction("Index", "Home"); 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } 
&nbsp; &nbsp; &nbsp; &nbsp; } 
&nbsp; &nbsp; &nbsp; &nbsp; else 
&nbsp; &nbsp; &nbsp; &nbsp; { 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ModelState.AddModelError("", 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "The user name or password provided is incorrect."); 
&nbsp; &nbsp; &nbsp; &nbsp; } 
&nbsp; &nbsp; }
}
Resumo
Ataques&nbsp;de redirecionamento&nbsp;aberto pode&nbsp;ocorrer&nbsp;quando&nbsp;o redirecionamento deURLs&nbsp;são passados&nbsp;como parâmetros&nbsp;na URL&nbsp;para&nbsp;um&nbsp;aplicativo.&nbsp;O&nbsp;ASP.NET&nbsp;MVC3&nbsp;&nbsp;inclui código para&nbsp;proteger contra&nbsp;ataques&nbsp;de redirecionamento&nbsp;aberto.Você&nbsp;pode adicionar esse código&nbsp;com algumas&nbsp;modificações&nbsp;para&nbsp;aplicações&nbsp;ASP.NET&nbsp;MVC 1.0&nbsp;e 2.0
fontes:http://www.asp.net/mvc/tutorials/preventing-open-redirection-attacks