2009-04-22 51 views
30

Actualmente tengo un enlace de conexión en mi aplicación que se ve algo como esto:ReturnUrl en ASP.NET MVC

<a href="/login?ReturnUrl=" + <%= Request.RawUrl %>>Login</a> 

quiero manejar el comando POST en la página de inicio de sesión en el controlador de la acción a continuación:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Login(string returnUrl) 
{ 
    // Authenticate user 

    return Redirect(returnUrl); 
} 

el problema aquí es si el RawUrl es algo con varios parámetros de URL como "CiertaPágina? param1 = 1 & param2 = 2 & param3 = 3", entonces el ReturnURL que se pasa a la acción de acceso se trunca después de la primera ampersand: "somepage? p aram1 = 1 ".

He intentado con UrlEncoding the RawUrl, pero eso parece marcar la diferencia. Parece que el marco MVC de ASP.NET aquí es UrlDecoding los parámetros de URL antes de asignarlos a los parámetros de acción del controlador, lo que termina eliminando los parámetros de URL adicionales que quiero ver en mi parámetro returnUrl.

¿Hay alguna forma de evitar esto? Sé que podría usar Request.Path y analizar los valores que necesito, pero pensé que primero vería si había un enfoque más limpio.

Respuesta

36

Probablemente esté codificando los enlaces incorrectamente. Sí, necesitan ser codificados. Aquí está cómo lo hacemos:

<a href="<%= Url.Action("Delete", "TimeRecord", 
    new RouteValueDictionary(new { id = timeRecord.AltId, 
    returnUrl=ViewContext.HttpContext.Request.Url.PathAndQuery })) %>"> 
+2

Esto es bueno; PathAndQuery no incluye el dominio, por lo que no es vulnerable a que un atacante use su servidor para redirigirlo a su sitio. – Will

+6

No diría que no eres vulnerable. La gente puede cambiar los datos del formulario con Fiddler y similares. Aún debe desinfectar el URI en el servidor. Por otro lado, es bueno no rellenar el formulario con datos incorrectos. :) –

+0

Se ve bien. Sin embargo, ten en cuenta que 'ViewContext.HttpContext.Request.Url' puede devolver nulo, lo que significa que puedes tener' NullReferenceException'. –

-2

Bien, su solución tiene un olor a él; No puedo poner mi dedo en un enlace que describa el ataque (tiene que ser un secuestro de sesión de algún tipo), pero redirigir ciegamente a través de una cadena de consulta tiene que ser un agujero de seguridad. Alguien responde o comenta con la información, pls.

Sin pensar en el aspecto de seguridad de esto, una solución rápida sería codificar Base64 entera la url de retorno. Aquí hay un código estoy totalmente ganked de a blog que puede o no puede trabajar:

public static string ToBase64(this HtmlHelper me, string toEncode) 
{ 
     byte[] toEncodeAsBytes 
      = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode); 
     string returnValue 
      = System.Convert.ToBase64String(toEncodeAsBytes); 
     return returnValue; 
} 

public static string FromBase64(this HtmlHelper me, string encodedData) 
{ 
     byte[] encodedDataAsBytes 
      = System.Convert.FromBase64String(encodedData); 
     string returnValue = 
     System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes); 
     return returnValue; 
} 
+2

. Creo que el ataque es algo así como: http://login.ebay.com/?returnUrl=www.MyFakeSiteThatLooksLikeEbay.com/lolyourescrewed.html para que las personas hagan clic en su enlace, inicien sesión en ebay y sean redirigidos a su sitio falso que se parece a ebay, donde le pedirá al usuario que confirme la información de su tarjeta de crédito. – Will

+0

Tiene sentido. La solución que Craig Stuntz publicó aborda esto usando PathAndQuery en su lugar. –

+2

No, no: pasa buenos datos sin un dominio, pero no soluciona el hecho de que si alguien le transfirió datos CON un dominio, aún necesita validar la entrada en el método de controlador – Jaykul

8

Asegúrese de que la URL codificar RawUrl antes de usarlo.

<%= Url.Encode(Request.RawUrl) %> 

Esto debería hacerlo por usted.

+2

Esta es la manera correcta de hacerlo – ajma

+0

Como dice la pregunta original, esto no funciona. –

+0

Esto funciona bien, la publicación original analizó mal lo que estaba sucediendo. –