Поиск PHP-скриптов, которые требуют register_globals - PullRequest
8 голосов
/ 03 февраля 2011

Я унаследовал веб-сервер, заполненный кодом, для которого требуется register_globals.Большая часть этого кода написана случайными людьми, которые приходили и уходили годами.Я исправил большинство из них в известных мне сценариях, но моя проблема в том, чтобы найти те, о которых я не знаю.

Я подумываю о написании приложения для сканирования всех каталогов на веб-сервере.определить PHP-скрипты, которые требуют register_globals.Есть ли хорошая стратегия для этого?

Один из рассмотренных мною способов заключается в том, чтобы заставить PHP сообщать обо всех ошибках, выполнять сценарии и проверять уведомления о неопределенных переменных.Я мог бы создать приложение, которое читает поток STDERR для этого.

Есть ли какие-нибудь лучшие методы, о которых вы можете подумать?

Ответы [ 5 ]

7 голосов
/ 03 февраля 2011

Большинство IDE покажет вам неопределенные переменные, например, PHPStorm . Вы можете разрешить ему сканировать все ваши исходные файлы, и вы будете уведомлены о неопределенных переменных во всем вашем коде, фактически исключая его выполнение.

Это, наверное, самый простой и безболезненный вариант. В качестве альтернативы вы можете написать свой собственный скрипт с использованием Tokenizer и идентифицировать все T_VARIABLE s, которые ранее не инициализировались с помощью конструкции T_VARIABLE '=' expr. Но это будет более подвержено ошибкам. Использование IDE, вероятно, даст вам лучшие результаты с меньшими усилиями.

3 голосов
/ 03 февраля 2011

Предполагая, что для отдельных файлов всегда используется включение или отключение register_globals, вы можете создать список всех имен элементов формы, которые передаются в сценарий, а затем проверить этот сценарий, если он использует $fieldname без указания $_REQUEST['fieldname'] (или$_POST, $_GET (массивы).

Ваш метод проверки уведомлений был бы приемлем, если бы вы могли гарантировать очень высокий охват кода при выполнении этих проверок (чтобы вы ничего не пропустили -открытые детали должны быть проверены вручную).

2 голосов
/ 03 февраля 2011

Хотя проверка логов на наличие признаков написания сценариев с ожиданием глобальных переменных может быть полезной, чтение кода - единственный способ действительно сделать это.Если вы хотите автоматизировать это, вам нужно создать интерпретатор PHP или полагаться на него;иначе вам суждено пропустить вещи, вложенные в условия, потенциальные уловки и т. д.

1 голос
/ 06 сентября 2017

Я сам столкнулся с этой проблемой в огромной кодовой базе с тысячами файлов.Вдохновленный решением, опубликованным @sschueller, я протестировал этот код auto_prepend_file, который регистрирует происшествия для расследования.Этот метод также следует использовать в сочетании с синтаксическим анализом / токенизацией для перехвата всех случаев.

<?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");
    }
}
1 голос
/ 27 июля 2015

Существует способ найти использование глобальных регистров , которые являются строками в исполняемом коде.Вы можете создать следующий скрипт и использовать опции PHP auto_prepend_file ini, чтобы добавить его к существующему коду.

<?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...
}

Для целых чисел и т. Д. Вам нужно исправить ваш PHP: https://gist.github.com/ircmaxell/1966809

...