2011-02-03 9 views
8

He heredado un servidor web lleno de código que requiere register_globals para estar activado. La mayor parte es un código personalizado escrito por personas al azar que han ido y venido a través de los años. He arreglado la mayoría en scripts que conozco, pero mi problema es encontrar los que no conozco.Búsqueda de scripts PHP que requieren register_globals

Estoy considerando escribir una aplicación para escanear a través de todos los directorios en el servidor web para identificar los scripts PHP que requieren register_globals. ¿Hay una buena estrategia para hacer esto?

Un método que he considerado implica de alguna manera forzar a PHP a informar todos los errores, ejecutar scripts y verificar avisos de variables indefinidos. Podría construir una aplicación que lea la secuencia STDERR para esto.

¿Hay algún método mejor que se te ocurra?

+3

+1 para no simplemente el uso de 'extract()' para obtener el código de mierda de trabajo, pero en realidad arreglando – ThiefMaster

Respuesta

6

La mayoría de los IDEs le mostrarán variables indefinidas, por ejemplo, PHPStorm. Puede dejar que escanee todos sus archivos de origen y se le notificará sobre variables indefinidas en todo su código, sin que realmente se ejecute.

Esta es probablemente la variante más sencilla e indolora. Alternativamente, usted podría escribir su propio script utilizando el Tokenizer e identificar todos los T_VARIABLE s, que no se inicializaron previamente utilizando un constructo T_VARIABLE'='expr. Pero esto será más propenso a errores. Usar el IDE probablemente le dará mejores resultados con menos esfuerzo.

+0

Gracias, no sabía acerca de PHPStorm. Lo probaré más tarde hoy. También podría echarle un vistazo a Tokenizer. Esa ruta probablemente sería exagerada solo para mí, pero tal vez construirá algo con ella y la lanzaré para que otros la usen. – Brad

+0

@Brad: ¿Y usaste PHPStorm? ¿O has escrito algo tú mismo? – NikiC

+0

Estoy esperando a PHPStorm para que me responda acerca de mi licencia educativa gratuita. Ellos tienen un proceso de aprobación manual, parece. Al examinarlo, creo que hará el trabajo, o al menos ayudará significativamente. – Brad

3

Suponiendo archivos individuales siempre están utilizando register_globals activado o desactivado, puede crear una lista de todos los nombres de los elementos del formulario que se someten a un guión y luego se marca esta secuencia de comandos si se trata de utilizar $fieldname sin contener $_REQUEST['fieldname'] (o el $_POST, $_GET matrices).

Su método de "verificación de avisos" estaría bien si puede garantizar una cobertura de código muy alta al hacer esos controles (para asegurarse de que no se perdió nada, las piezas descubiertas deben verificarse manualmente).

+0

El problema es que no tengo manera de saber lo que está siendo sometido a un guión.No estoy hablando de unas pocas páginas aquí o allá, o incluso contenía aplicaciones ... sino más de 200,000 páginas web y scripts PHP. Muchos de estos scripts hacen referencia a otros scripts y algunos scripts manejan publicaciones de otros servidores/sitios. Buen punto sobre posibles rutas de código. Asumí que PHP generó un 'E_NOTICE' para esto en cualquier lugar del código, pero me di cuenta de que no sería posible hasta que ejecutara el código usando la referencia. – Brad

2

Al examinar los registros de los síntomas escritos de scripts esperando que los valores globales puedan ser útiles, leer el código es la única forma de hacerlo. Si quisiera automatizar esto, necesitaría construir o confiar en un intérprete PHP; de lo contrario, está destinado a perder cosas anidadas en condiciones, evaluaciones potenciales, etc.

+0

Gracias por sus comentarios. Esperaba encontrar una manera de confiar en PHP.exe, pero como ha señalado, simplemente ejecutando perderá elementos en declaraciones condicionales. Parece que el método manual puede ser el camino a seguir, si algún IDE de PHP no puede ayudarme a identificarlos. – Brad

1

Hay una manera de localizar los usos de registrar global que son cadenas en el código de ejecución. Puede crear la siguiente secuencia de comandos y usar las opciones ini de PHP auto_prepend_file para anteponerla a su código existente.

<?php 

class revealGlobalsUsage { 

    public $globalName; 
    public $globalVal; 

    public function __construct($name, $val) 
    { 
     $this->globalName = $name; 
     $this->globalVal = $val; 
    } 

    public function __toString() 
    { 
     $backtrace = debug_backtrace(); 

     // log backtrace here... 

     return $this->globalVal; 
    } 
} 

// overwrite globals that have been set from GET and POST requests 
foreach ($_REQUEST as $name => $val) { 
    // Strings that are cast to integers will fail as there 
    // is no __toString equivalent for integers/bool/float etc. 
    if (is_string($val) && !is_numeric($val)) { 
     $GLOBALS[$name] = new revealGlobalsUsage($name, $val); 
    } 

    // You can log all GET/POST requests here... 
} 

Para enteros, etc. que se necesitan para reparar su PHP: https://gist.github.com/ircmaxell/1966809

1

me encontré con este problema a mí mismo en una enorme base de código con miles de archivos. Inspirado por la solución publicada por @sschueller, he probado este código auto_prepend_file que registra las ocurrencias para su investigación. Este método también se debe usar junto con el análisis/tokenización para capturar todas las ocurrencias.

<?php 

$vars = get_defined_vars(); 

foreach ($vars as $var => $value) { 
    if (in_array($var, array('$_SERVER', '$_REQUEST', '$_GET', '$_POST', '$_COOKIE', '$_SESSION', '$_FILES', '$_ENV'))) { 
     // only examine the local symbols, not superglobals 
     continue; 
    } 

    if (array_key_exists($var, $_REQUEST) && $value == $_REQUEST[$var]) { 
     error_log(sprintf("register_globals reliance detected in %s for variable %s=%s", $_SERVER['SCRIPT_FILENAME'], $var, $value), 3, "/var/tmp/register_globals.log"); 
    } 
} 
Cuestiones relacionadas