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?

È stato utile?

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_VARIABLEs, 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");
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top