Trovare script PHP che richiedono register_globals
-
28-10-2019 - |
Domanda
Ho ereditato un server Web pieno di codice che richiede register_globals
essere sul. La maggior parte è un codice personalizzato scritto da persone a caso che sono arrivate e andate nel corso degli anni. Ne ho risolto la maggior parte nelle sceneggiature che conosco, ma il mio problema è trovare quelli che non conosco.
Sto pensando di scrivere un'applicazione per scansionare ogni directory sul server Web per identificare gli script PHP che richiedono register_globals
. C'è una buona strategia per farlo?
Un metodo che ho considerato implica in qualche modo costringere PHP a segnalare tutti gli errori, eseguire script e verificare gli avvisi variabili indefiniti. Potrei creare un'applicazione che legge il STDERR
flusso per questo.
Ci sono metodi migliori a cui puoi pensare?
Soluzione
La maggior parte degli ides ti mostrerà variabili indefinite, Phpstorm lo fa ad esempio. Puoi lasciarlo scansionare tutti i file di origine e verrai avvisato sulle variabili indefinite in tutto il codice, Whiteout lo eseguono effettivamente.
Questa è probabilmente la variante più semplice e indolore. In alternativa potresti ovviamente scrivere il tuo script utilizzando il Tokenizer e identifica tutto T_VARIABLE
s, che non sono precedentemente inizializzati usando a T_VARIABLE
'='
expr
costruire. Ma questo sarà più soggetto a errori. L'uso dell'IDE probabilmente ti darà risultati migliori con meno sforzo.
Altri suggerimenti
Supponendo che i file singoli utilizzino sempre o si spegne o spento, è possibile creare un elenco di tutti i nomi degli elementi del modulo che vengono inviati a uno script e quindi controllare questo script se utilizza $fieldname
senza contenere $_REQUEST['fieldname']
(o il $_POST
, $_GET
array).
Il tuo metodo "Controllo per gli avvisi" andrebbe bene se puoi garantire una copertura del codice molto elevata mentre fai quei controlli (per assicurarti di non perdere nulla: le parti scoperte devono essere controllate manualmente).
Mentre esaminare i tuoi registri per i sintomi degli script scritti in attesa di vari globali possono essere utili, leggere attraverso il codice è l'unico modo per farlo davvero. Se si desidera automatizzare questo, dovresti costruire o fare affidamento su un interprete PHP; Altrimenti sei destinato a perdere cose nidificate all'interno di condizioni, potenziali evali, ecc.
C'è un modo per individuare gli usi di Registrati in globali che sono stringhe nel codice in esecuzione. È possibile creare il seguente script e utilizzare PHP Auto_Pripend_file Opzioni INI per prepararlo al tuo codice esistente.
<?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...
}
Per i numeri interi ecc. Dovresti rattoppare il tuo PHP: https://gist.github.com/ircmaxell/1966809
Mi sono imbattuto in questo problema in un'enorme base di codice con migliaia di file. Ispirato dalla soluzione pubblicata da @sschueller Ho testato questo codice Auto_Pripend_File che registra gli eventi per le indagini. Questo metodo dovrebbe essere utilizzato anche insieme all'analisi/tokenizzazione per catturare tutte le occorrenze.
<?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");
}
}