Ver Mensaje Individual
  #1 (permalink)  
Antiguo 10/01/2012, 06:35
pintix
 
Fecha de Ingreso: octubre-2004
Ubicación: Barcelona
Mensajes: 195
Antigüedad: 20 años, 1 mes
Puntos: 7
[Aporte] Clase para comprobar datos de un GET entre páginas

He creado una clase en PHP para comprobar que los pares de clave y valor de un GET a los que enlazamos en un una página no han sido modificados por el usuario en la barra de direcciones del navegador en la página de destino.

Puede ser útil, por ejemplo, cuando queremos dar listas con soluciones a ejercicios a medida que avanza un curso. Con unos pares solucion / tema para que si una combinacion de número de solucion y tema no esta en lista de la pagina in¡cial no pueda ser visto por el usuario utilizando la barra de direcciones. También se puede cambiar la clave para cada usuario para identificar los que intentan saltarse la proteccion o para generar links que sólo puedan ser vistos por este usuario.

La forma en que lo hace es convirtiendo con serialize en una cadena un array con los datos que irán en el GET añadiendo un elemento más con una palabra secreta. Con la cadena resultante generamos un hash MD5 que añadiremos al GET final. En la página siguiente hacemos el mismo proceso para comprobar que el GET que nos ha llegado genera la misma clave MD5.

seguridadpareshash.php
Código PHP:
<?php
/** 
 *  Seguridad GET con un hash MD5
 *    
 *  Comprueba en el script de destino que los datos de un query al que 
 *  enlaza nuestra pagina son los originales
 *    
 *  Puede ser útil, por ejemplo, cuando queremos dar listas con 
 *  soluciones a ejercicios a medida que avanza un curso. Con unos pares
 *  solucion / tema para que si una combinacion de número de solucion 
 *  y tema no esta en lista de la pagina no pueda ser visto por el 
 *  usuario utilizando la barra de direcciones. También se puede cambiar
 *  la clave para cada usuario para identificar los que intentan 
 *  saltarse la proteccion.
 *  
 *  Funciones de generacion:
 *      GeneraGETconHash -- Devuelve ?un=valor&otro=dato&sp=hash
 *      GeneraURL -- Devuelve unapagina.php?un=valor&otro=dato&sp=hash
 *      GeneraEnlace -- Devuelve <a href="unapagina.php?un=valor&otro=dato&sp=hash">Texto</a>
 *  
 *  Funcion de comprobacion:
 *      CompruebaGETconHash
 *  
*/

class CompruebaGetEntrePaginas
{    
    private 
$palabraSecreta;
    
    function 
__construct()
    {
        
$this->palabraSecreta $this->GeneraPalabraSecreta ();
    }
    
    
// Genera un GET con un codigo de comprobacion al final
    
public function GeneraGETconHash ($ArrayVariables)
    {        
        
$GETconHash "";
        
$Liga "";
        foreach (
$ArrayVariables as $UnaLlave => $UnValor){
            
$GETconHash .= $Liga.$UnaLlave."=".$UnValor;
            
$Liga "&";
        }
        
$GETconHash "?".$GETconHash;
        
$ArrayVariables["palabraSecreta"] = $this->palabraSecreta;
        
$ClaveHash hash ("md5",serialize($ArrayVariables));
        
$GETconHash .= $Liga."ps=".$ClaveHash;
        return 
$GETconHash;
    }
    
    
// Genera una URL completa, simplemente sirve para que haya menos 
    // funciones en la creación de la lista 
    
public function GeneraURL ($ElArrayVariables,$NombreScript "")
    {        
        
$elGETconHash $this->GeneraGETconHash ($ElArrayVariables);
        
$PrefijoURL = (empty($NombreScript))? $_SERVER["PHP_SELF"] : $NombreScript;
        
$URLcompleta $PrefijoURL.$elGETconHash
        return 
$URLcompleta;
    }
    
    
// Genera un enlace completo
    
public function GeneraEnlace ($ElArrayVariables,$TextoEnlace,$NombreScript ""){
        
$laURL $this->GeneraURL($ElArrayVariables,$NombreScript);
        return 
'<a href="'.$laURL.'">'.$TextoEnlace.'</a>';
    }
    
    
// Comprueba que no se ha modificado la URL
    
public function CompruebaGETconHash ()
    {
        
$ArrayTrabajo $_GET;
        
$ValorHash array_pop ($ArrayTrabajo);
        
$ArrayTrabajo["palabraSecreta"] = $this->palabraSecreta;
        
$ValorEsperadoHash hash ("md5",serialize($ArrayTrabajo));
        
$comparacionValores = ($ValorHash === $ValorEsperadoHash)? TRUE FALSE;
        return 
$comparacionValores;
    }
    
    
// Para mas seguridad se deberia reescribir esta funcion para leer el valor de una base de datos
    
private function GeneraPalabraSecreta ()
    {
        
// Este valor de retorno debe cambiarse para mas seguridad
        
return 'flghusf';
    }
}
?>
lista.php
Código PHP:
<?php
include_once ("seguridadpareshash.php");

// Iniciamos la clase de creacion/comprobacion
$CreaCompruebaURL = new CompruebaGetEntrePaginas ();

// En esta variable ponemos el nombre del script PHP. Si esta vacio
// o no esta definido se usa $_SERVER["PHP_SELF"]
$NombreScriptDestino "resultadosprueba.php";

// Datos que iran en el GET y en el texto del enlace
$DatosGet = Array("solucion" => "12","tema" => "25");
$TextoEnlace "Resultados al ejercicio 12 del tema 25";

// Mostramos el resultado en pantalla
print ($CreaCompruebaURL->GeneraEnlace ($DatosGet,$TextoEnlace,$NombreScriptDestino));
?>
resultadosprueba.php
Código PHP:
<?php
include_once ("seguridadpareshash.php");

$CreaCompruebaURL = new CompruebaGetEntrePaginas ();

// Comprobamos que coincide elcontenido de las variables de GET con el hash MD5 final
if ($CreaCompruebaURL->CompruebaGETconHash ()){
    echo 
"Datos URL originales";
} else {
    echo 
"Datos URL modificados";
}
?>