Asegurando redirecciones de inicio de sesión

4

Si alguien accediera a una página protegida mientras estaba desconectado, sería redirigido a una página de inicio de sesión:

/login?next=/something/123/manage?sort=desc

Si el inicio de sesión se realiza correctamente, se deben redirigir a la página que pretenden ver:

if verify_creds(user, password):
    login(user)
    return redirect(request.args['next'])

¿Cómo verificar que un atacante no puede usar el siguiente parámetro para visitar un sitio de phishing? ¿Es suficiente verificar si el próximo inicio es / , es decir, un enlace relativo o debo intentar verificar si es una ruta válida en mi aplicación?

    
pregunta aitchnyu 04.05.2017 - 19:07
fuente

2 respuestas

3
  

¿Es suficiente para comprobar si el próximo comienzo con / , es decir, un enlace relativo

No, no es suficiente. Tome este script como ejemplo:

<?php header('Location: ' . $_GET['next']); ?>

Un atacante podría activar un redireccionamiento abierto a través de redirect.php?next=//example.com/ . Su navegador interpreta esto como una URL absoluta utilizando el mismo protocolo.

  

¿Debo intentar comprobar si es una ruta válida en mi aplicación?

Esa sería la solución más segura. Si la verificación de rutas válidas no es una opción, debería asegurarse de que la URL comience con /[a-zA-Z0-9] (es decir, una barra y un carácter alfanumérico).

Comprobar que comienza con / y no con // , como sugiere @BenoitEsnard, puede ser seguro en algunos contextos, pero no siempre es suficiente. Tome este ejemplo (e ignore el problema obvio de XSS por causa del argumento):

<meta http-equiv="refresh" content="0; url=<?php echo $_GET['next']; ?>">

Aquí, un atacante podría lograr un redireccionamiento a través de redirect.php?next=/%26sol;example.com/ , que codifica en HTML el segundo / y no sería detectado por un filtro que verifique el comienzo de // .

La hoja de trucos OWASP sobre redirecciones sin validar tiene algunos consejos adicionales.

    
respondido por el Arminius 04.05.2017 - 19:55
fuente
2

No, no es suficiente comprobar que next comienza con / .

Las URL relativas al protocolo, como //example.org , podrían usarse para evitar esta comprobación y redirigir al usuario a un dominio externo.

Verificar que la URL comience con / y no comience con // debería mitigar completamente este problema.

    
respondido por el Benoit Esnard 04.05.2017 - 19:45
fuente

Lea otras preguntas en las etiquetas