Nueva pregunta

Pregunta:

Fecha: 01-03-2017 02:58:56 (En Español)

Función redirectTo: redirección PHP y Javascript simplificada[Resuelta]

Hola comunidad, el día de hoy les quería compartir una función de mi autoría para simplificar el código requerido ante una redirección, espero que les sea de interés.

<?php
/**
 * Función redirectTo
 * @author Fernando Mosquera - PHPCentral.com
 * @param String $urlDestino: dirección url destino del redirect
 */
function redirectTo($urlDestino = false) {
    if ($urlDestino === false) {
        $urlDestino = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
    }
    
    if (empty($urlDestino)) { //<-- aquí se podría mejorar controlando además si el destino es o no valido.
        //si no se especificó una url destino y no se encontro un referer, indico destion por defecto al index.php
        $urlDestino = 'index.php';
    }

    //verifico si ya fue enviado algun header:
    if (!headers_sent()) {
        //si no fue enviado un header, hago un redirect con PHP
        header('Location: ' . $urlDestino);
        exit;
    } else {
        //si ya fue enviado un header, hago un redirect con Javascript
        echo '<script type="text/javascript">window.location="' . $urlDestino . '";</script>';
        exit;
    }
}


Algunos comentarios de la función:

* Si no se especifica el parámetro $urlDestino, por defecto se hace un redirect to referer (envía al usuario por donde vino).

* Luego de invocar la función redirectTo el script PHP será cortado por medio de la función "exit()", por lo que no se ejecutará cualquier sentencia adicional que esté por debajo de la invocación.

* Forma en que se determina si realizar el redirect por medio de PHP o Javascript: antes de utilizar la función header() se verifica que no se halla enviado algun otro header, ya que sino la función header fallará. El envíar un caracter html, por medio de un echo, print, o cualquier otra función que imprima en el buffer de PHP y/o dejar un espacio en blando fuera de las etiquetas PHP envía un header html (no necesariamente un header se envía por medio de la función header()). Si fue enviado o no se verifica por medio de la función "headers_sent()", la cual comprueba si se ha enviado alguna cabecera/header y devuelve true en caso de exito.


Espero que este aporte les sirva y puedan utilizarlo en más de un proyecto.

Saludos a todos y como siempre buen código!
Etiquetas: Aporte - Mejores Prácticas - PHP - PHP header - Redirect Votos: 7 - Respuestas: 9 - Vistas: 29 Compartir en: Google Facebook Twitter LinkedIn Link
 

Respuestas:

  • Fecha: 01-03-2017 09:05:12 Muy bueno
    Fernando muchas gracias por compartir.
    En muchos casos se necesita redirigir.
    Saludos
      Votos: 0 - Link respuesta
     
  • Fecha: 01-03-2017 09:54:39 Gracias Walter por tu comentario.

    He recibido comentarios en Facebook de lo más variados, y algunos que merecerían estar aquí y ser votados... (con mejoras para la función), lastima que no todos se suman a la comunidad, aunque desde Facebook es tan fácil...

    En fin, saludos a todos!
      Votos: 1 - Link respuesta
     
  • Fecha: 01-03-2017 19:13:21 Seria bueno que los comentarios de otros usuarios estuvieran aquí, enriquecería mucho las diferentes opiniones las cuales aportarían valor y hasta mejorarian o darina otro punto de vista sobre el codigo.
    Esperemos que se sumen
    Saludos
      Votos: 1 - Link respuesta
     
  • Fecha: 06-03-2017 19:10:25 Fernando, sería bueno que si ellos no quieren compartirlo por aquí entonces lo compartieras tú.

    En mi caso veo algunas malas prácticas:

    1. Inconsistencia en el parámetro de la función. El comentario dice que es un string y su valor por defecto es un boolean y después dentro del código asignas un string de nuevo.
    2. En lo posible trata de evitar la sentencia else

    Saludos!
      Votos: 1 - Link respuesta
     
  • Fecha: 27-03-2017 21:06:59 Un par de problemas de seguridad con ese codigo

    - Vulnerable a XSS.
    - Es mejor declarar una variable $DEFAULT_REDIRECT_URL y no depender del super global $_SERVER directamente ya que segun de la configuracion de PHP es facilmente posible hacer un override de sus valores
      Votos: 1 - Link respuesta
     
  • Fecha: 28-03-2017 05:58:44 Hola Abraham, agradecería puedas explicar un poco más tus puntos, ya que no veo problema de vulnerabilidad XSS y con respecto a utilizar el array $_SERVER o no, tampoco veo el problema, ya que si vamos a desconfiar de la información de este array de PHP también deberíamos hacerlo con todos los otros (por ejemplo $_SESSION, $_POST, $_GET, etc.) y si ese fuera el caso tendrías un grave problema de seguridad que nada tiene que ver con la función redirectTo().

    Al margen de disentir, muchas gracias por tu punto de vista, esta bueno que se puedan debatir mejoras y/o correcciones.

    Saludos y buen código!
      Votos: 1 - Link respuesta
     
  • Fecha: 28-03-2017 10:55:04 Claro Fernando, a lo que me refiero es que cuando vas a hacer algo como esto

    echo '<script type="text/javascript">window.location="' . $urlDestino . '";</script>';


    deberias de "sanitizar" el input con al menos stripslashes, strip_tags para evitar que la variable $urlDestino tenga valores maliciosos.

    Por ejemplo $urlDestino podria tener algo como lo siguiente

    // Ataque  XSS 
    $urlDestino = '#test"; /* aqui va mi script para un keylogger o sniffer */</script>';


    Respecto a $_SERVER dependiendo del valor de la directiva "variables_order" y "register_globals" es posible hacer un override de los valores de los superglobals. Tambien es posible manipular HTTP_REFERER por medio de un proxy (cosa que es comun).

    Saludos!
      Votos: 1 - Link respuesta
     
  • Fecha: 28-03-2017 11:24:29 Fernando, lo que comenta Abraham es cierto, debes de desconfiar de muchos de los parametros que vienen en la superglobal SERVER, sobre todo los que proporcionan informacion del protocolo de navegacion (parte de una peticion HTTP que como bien menciona Abraham pueden ser facilmente editadas).

    De hecho la regla de oro es: Desconfia de todo lo que venga de fuentes externas (sobre todo tus usuarios e incluso de tus bases de datos ;)), ergo las superglobales como POST, GET, REQUEST siempre deben tratarse como inseguras pues son la fuente primaria de ataques.
      Votos: 0 - Link respuesta
     
  • Fecha: 29-03-2017 04:33:12 Ante todo muchas gracias por sus respuestas.

    Abrahama: entiendo lo que dices, pero sigo disintiendo con lo que comentas, ya que no aplica a este caso y me paso a explicar.

    * $urlDestino no es un parámetro ingresado por el usuario: sanitizar o no una parámetro de una función es valido siempre y cuando el mismo no pueda ser garantizado por tu sistema, ahora bien, el parametro $urlDestino no es informado/definido por el usuario, si no por ti del lado del servidor, no hay forma de que te inyecten código ahí, porque el parámetro lo manejas tu.

    * variables_order: establece el orden de interpretación de variables, no veo el problema, a lo sumo si esta deshabilitado el array $_SERVER podrías fallar la función (pero hasta la fecha no he visto un servidor con esta configuración), y si esto es un problema nuevamente no es de la función, sino de una mala configuración de tu modulo PHP y código solidario ajeno a la función.

    * register_globals: esta característica ha sido declarada obsoleta desde PHP 5.3.0 y su uso está totalmente desaconsejado. Hay muchas ataques conocidos de la mano de esta directiva y un mal código, no aplicable a este caso.

    * manipulación de la clave $_SERVER['HTTP_REFERER']: si bien el HTTP_REFERER puede ser manipulado por el usuario esto no representa un problema, ya que si el usuario informa otro referer distinto al real a lo sumo es redireccionada a otra ubicación (sería lo mismo que el usuario pusiera ese referer en el browser y le hiciera un GET, no hay amenaza alguna).

    Ernesto: soy consciente de lo que dices, pero las entradas del array $_SERVER son creadas por el servidor web y a lo sumo no estan disponibles, y en el caso que el referer sea manipulado por el usuario me remito al último punto en mi respuesta a Abrahama.

    Al margen de todo lo dicho, si observan en la línea 12 comento que la función puede ser mejorada controlando si el destino es valido o no.
    ...
    if (empty($urlDestino)) { //<-- aquí se podría mejorar controlando además si el destino es o no valido.
    ...
    

    Nota extra: para mayor tranquilidad (en el caso de usar esta función en un código mal orquetado, solidario a x ataque) en el IF mencionado se podría validar que la variable $urlDestino contenga una URL valida (que sea realmente una URL, ya con esto no deberás sanitizar nada). También podrás validar que dicha URL tenga el domino de tu sistema, etc...

    Nuevamente muchas gracias a todos por colaborar con sus mejoras, comentarios, advertencias, etc. todo suma.

    Saludos a todos y buen código!
      Votos: 1 - Link respuesta
     
Para participar activamente de la comunidad primero debes autenticarte, ingresa al sistema.Iniciar Sesión
 
frjcbbae garagebible.com