Comprobando el parámetro "devolver" en la página de inicio de sesión

5

Mi página de inicio de sesión acepta el parámetro "retorno", que debe contener un URI para redirigir al usuario si no inició sesión y trató de acceder a la página a la que no pueden acceder usuarios no autenticados. Podría ser cualquier cosa de mi sitio.

¿Cómo verifico correctamente ese parámetro en el código de mi servidor, antes de devolver el estado HTTP 302 con ese URI al usuario después de que se haya autenticado correctamente en la página de inicio de sesión?

¿Es suficiente comprobar que uri[0] == '/' && uri[1] != '/' (por lo que un usuario malintencionado no envía una solicitud como /login?return=http://google.com )?

¿Puede un usuario malintencionado construir un uri complicado que enviará al usuario víctima a problemas? Por supuesto, asumo que otras páginas no contienen vulnerabilidades de XSS, la solicitud GET no cambia nada en la base de datos, etc.

Si un usuario malintencionado puede engañar a la víctima para que haga clic en su enlace y el usuario víctima ya haya iniciado sesión, ocurrirán cosas de todos modos y no puedo hacer nada para evitar eso, excepto implementar medidas de seguridad conocidas, como la protección CSRF, etc. .

    
pregunta vbezhenar 06.01.2015 - 13:38
fuente

8 respuestas

3

La vulnerabilidad de no comprobar un parámetro al que luego redirecciona se llama Open redirect . Esto es principalmente un riesgo de suplantación de identidad (phishing), ya que un usuario puede hacer clic en un enlace que va a www.google.com (por ejemplo, para este argumento que está ejecutando Google) al revisar la URL antes de hacer clic. Sin embargo, luego son redirigidos por el redireccionamiento abierto a www.evil.com , donde no notan que la URL ha cambiado porque la página tiene el mismo aspecto que Google y luego ingresan su nombre de usuario y contraseña de Google en el formulario, enviando sus credenciales a www.evil.com .

Simplemente valide return para asegurarte de que sea solo una ruta relativa.

Por ejemplo, en .NET puedes llamar a Uri.IsWellFormedUriString con UriKind configurado a Relative .

Para otros idiomas, pueden estar disponibles métodos similares.

Si necesita escribir su propio cheque, debe estar bien:

uri[0] == '/' && uri[1] != '/'

es decir, el primer carácter es / y el segundo no es / .

RFC 3986 detalla el formato de una URL relativa:

 relative-ref  = relative-part [ "?" query ] [ "#" fragment ]

      relative-part = "//" authority path-abempty
                    / path-absolute
                    / path-noscheme
                    / path-empty

Entonces, mientras esté marcando, el primer carácter es / y excluye la referencia de la ruta de la red:

  

Una referencia relativa que comienza con dos caracteres de barra diagonal se denomina      una referencia de ruta de red

que ahora utilizan los navegadores modernos como URL relativa al protocolo , está asegurando que la URL es relativa y segura contra vulnerabilidades de redireccionamiento abiertas.

    
respondido por el SilverlightFox 07.01.2015 - 12:14
fuente
5

La mejor manera es crear una lista blanca de posibles URL, si la redirección no forma parte de la lista blanca, puede redirigirla a una página de inicio predeterminada. Sin embargo, esto no es demasiado flexible.

También puede hacer una expresión regular de todo el asunto para garantizar que el inicio de la URI sea su sitio web, por ejemplo. enlace y que lo que viene después de su último / solo contiene números, letras y & o? y no permitir ningún otro carácter (también podría trabajar con rutas relativas).

    
respondido por el Lucas Kauffman 06.01.2015 - 14:42
fuente
4

Depende de lo elegante que quieras obtener. Me imagino que esta lógica encajaría a la perfección:

// Is this a full URL string?
if(is_valid_url(trim($uri)))
{
    // Redirect user to the default landing page
    redirect(default_url_within_site);
}
else
{
    // It is probably an actual URI string so just append it to your site name
    redirect('www.yoursite.com/'.$uri);
}
    
respondido por el MonkeyZeus 06.01.2015 - 19:55
fuente
1

trata TODAS las entradas de los usuarios como MAL, lo que significa. después de limpiar su entrada, reconstruya la url de redireccionamiento para que siempre apunte a su sitio (dominio) y elimine todos los argumentos que no estén en uso para su sistema o que sean "especiales" en html (elimine los url codificados). O mejor aún, solo trabaje con la parte "incluida en la lista blanca" de su sitio para regresar, y de otras maneras vuelva al "frente". De esta manera, solo puede ir a un conjunto limitado de páginas de 'aterrizaje' para las que es mucho más fácil de desinfectar.

    
respondido por el LvB 06.01.2015 - 14:41
fuente
1

Debes verificar todo el parámetro, no solo los dos primeros caracteres.

A pesar de que una redirección (suponiendo que solo use ese parámetro en el encabezado Location ) no es tan explotable como cualquier otra página en XSS, se han detectado vulnerabilidades en varios navegadores que podrían llevar a un XSS exitoso a través de redirecciones 30x tanto en Opera como en Firefox.

Recomendaría usar expresiones regulares para permitir solo ciertos caracteres "seguros" en ese parámetro, como mayúsculas, minúsculas, números, puntos y quizás una barra.

    
respondido por el NuTTyX 06.01.2015 - 14:41
fuente
1

La idea difícil toma todos los resultados como buenos, pero antes de redireccionar con curl, envíe una solicitud con la siguiente opción habilitar y verifique si el resultado es el host de su host

    
respondido por el Danile 07.01.2015 - 02:07
fuente
1

Por lo que yo sé, esto se llama una vulnerabilidad de redireccionamiento abierto:

enlace

Se puede evitar fácilmente cifrando el parámetro de redireccionamiento con algo como AES y luego url / base 64 que lo codifica.

    
respondido por el Petah 07.01.2015 - 02:13
fuente
0

El riesgo no es alto. El adversario debe poder enviar al usuario a una URL con un parámetro de retorno de su elección. Si el adversario pudo hacer eso, es muy probable que hayan enviado al usuario a su propio dominio en primer lugar en lugar de a su página de inicio de sesión.

Podría ser posible abusar en ciertos ataques de phishing. Pero la mayoría de los ataques de phishing simplemente copiarían el diseño de su página de inicio de sesión en una URL en su propio dominio.

Dicho esto, la defensa en profundidad suele ser una buena idea. Por lo tanto, aún vale la pena considerar cómo se puede validar el parámetro de retorno.

Otros han señalado que puede crear una lista blanca de URL permitidas. Un enfoque diferente sería aplicar un código de autenticación de firma o mensaje a la URL.

Si http://example.com/private requiere autenticación, podría redirigir a http://example.com/login?return=http://example.com/private&mac=Tej3M9aawsaCihGGXBGABPyyYsQQPX1o3PQeGg . La página de inicio de sesión puede verificar que el MAC sea válido para la URL de retorno especificada, y no redirigir a la URL de retorno si no tiene un MAC válido. Puede ser una buena idea que el MAC dependa no solo de la URL de retorno sino también de una cookie.

    
respondido por el kasperd 07.01.2015 - 01:58
fuente

Lea otras preguntas en las etiquetas