Limitar el parámetro de redireccionamiento a un dominio específico

2

El uso de PHP para establecer un encabezado de ubicación para redirigir (por ejemplo, al iniciar sesión después de cerrar sesión) puede ser inseguro si la redirección no especifica un dominio. Aquí hay un ejemplo:

header('Location: ' . $_GET['redirect']);

¿Existe una forma sencilla (no una lista blanca) de garantizar que la redirección no abandone el dominio? Tal vez algo como:

header('Location: /' . $_GET['redirect']); //start forward slash guarantees domain cant change?
    
pregunta tau 25.01.2018 - 00:17
fuente

2 respuestas

1
  

Tal vez algo como:

header('Location: /' . $_GET['redirect']); //start forward slash guarantees domain cant change?

No, una barra diagonal hacia adelante no no lo protege contra open redirects .

Un atacante podría consultar el script como ...

https://yoursite.example/file.php?redirect=/malicious.example

... que da como resultado Location: //malicious.example , que se trata como una URL relativa al protocolo que su navegador entenderá como una redirección a https://malicious.example .

Esta notación también funciona para las URL en otros contextos, por ejemplo, Enlaces HTML:

'<a href="//malicious.example">...</a>'.
  

¿Existe una forma sencilla (no una lista blanca) de garantizar que la redirección no abandone el dominio?

Un enfoque alternativo simple a la respuesta de @ David es buscar una barra y un carácter alfanumérico posterior, o la secuencia inicial /./ . Ambos nunca pueden llevar a la representación de una URL absoluta.

Tenga en cuenta que en versiones anteriores de PHP también tenía que desinfectar un valor de encabezado proporcionado por el usuario para nuevas líneas / retornos de carro, ya que de lo contrario podría habilitar los ataques de inyección de encabezado.

De tu comentario de seguimiento:

  

¿Qué pasa si comenzó con un protocolo y un nombre de host? por ejemplo, header('Location: https://domain.com' . $_GET['redirect']) hay una manera de evitar eso?

Esto solo es seguro si obliga a que el primer carácter proporcionado por el usuario sea una barra. De lo contrario, un ataque simple sería .malicious.example , redirigiendo al subdominio controlado por el atacante https://domain.com.malicious.example . Alternativamente, @malicious.example también funciona, ya que convierte a domain.com en el nombre de usuario para autenticar con el dominio malicious.example .

    
respondido por el Arminius 25.01.2018 - 00:58
fuente
2

Su ejemplo es trivialmente anulable:

http://yoursite.com/page.php?redirect=/www.google.com

da como resultado una redirección de:

//www.google.com

Que es una URL válida.

Debería analizar la URL utilizando una función como parse_url y luego reconstruir una URL con el componente de ruta que desee. Por ejemplo, podría usar solo los fragmentos path y query para crear una URL que redireccione solo dentro del protocolo, puerto y host actuales.

    
respondido por el David 25.01.2018 - 00:45
fuente

Lea otras preguntas en las etiquetas