Санитарная обработка пользовательских регулярных выражений в PHP - PullRequest
5 голосов
/ 03 марта 2010

Я хочу создать веб-сайт, на котором пользователи могут проверять регулярные выражения (их уже много ... например, таких: http://www.pagecolumn.com/tool/pregtest.htm).) В основном пользователь предоставляет регулярное выражение и образец текста, а также результаты оценки регулярных выражений будут отображены.

Я хочу оценить регулярное выражение на стороне сервера с помощью PHP-функций preg_ *. Есть ли способ дезинфицировать поставленное регулярное выражение? О каких уязвимостях в безопасности я должен беспокоиться?

Ответы [ 5 ]

3 голосов
/ 03 марта 2010

Я думаю, что PHP сам проверит регулярное выражение. Вот пример сценария, который я сделал:

// check for input, and set max size of input
if(@!empty($_POST['regex'])
    && @!empty($_POST['text'])
    && strlen($_POST['regex'])<1000
    && strlen($_POST['text'])<2000
    ){
    // set script timeout in case something goes wrong (SAFE MODE must be OFF)
    $old_time=ini_get('max_execution_time');
    if(!set_time_limit(1)) die('SAFE MODE MUST BE OFF'); // 1 sec is more then enough

    // trim input, it's up to you to do more checks
    $regex=trim($_POST['regex']);
    // don't trim the text, it can be needed
    $input=$_POST['text'];
    // escape slashes
    $regex=preg_replace('/([\\/]+)?//', '\/', $regex);

    // go for the regex
    if(false===$matched=@preg_match('/'.$regex.'/', $input, $matches)){
            // regex was tested, show results
            echo 'Matches: '.$matched.'<br />';
            if($matched>0){
                    echo 'matches: <br />';
                    foreach($matches as $i =>  $match){
                            echo $i.' = '.$match.'<br />';
                }
            }
    }
    // set back original execution time
    set_time_limit($old_time);
}

В любом случае, НИКОГДА не используйте eval () для строк, отправленных пользователем .

Кроме того, вы можете выполнить простую минималистичную дезинфекцию, но это ваше дело. ;)

1 голос
/ 03 марта 2010

Если вы разрешите пользовательские значения для preg_replace , убедитесь, что запретил флаг e ! В противном случае злоумышленник может удалить весь ваш сайт или еще хуже.

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

0 голосов
/ 03 марта 2010

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

В противном случае, меня беспокоит только то, что пользователь может предоставить вредоносное регулярное выражение в том смысле, что оно может содержать неправильное сложное регулярное выражение, и я не уверен, что есть способ проверить это.

Одна мысль состоит в том, что вы можете сделать свой анализатор регулярных выражений полностью клиентским, выполнив это в JS, но есть несоответствия между preg-функциями php и JavaScript-регулярными выражениями.

0 голосов
/ 03 марта 2010

Afaik теперь есть "уязвимости" при попытке оценить предоставленные пользователем регулярные выражения.Худшее, что может случиться, - как указывает Эрик, - атака DOS или фатальная ошибка в вашем скрипте.

Я боюсь сказать вам, что вы не сможете (даже теоретически) сделать этоsanitize "все возможные регулярные выражения там.Лучшее, что вы можете сделать, это проверить лексические и / или синтаксические ошибки.

0 голосов
/ 03 марта 2010

Единственная проблема, о которой я могу подумать, это то, что кто-то может DOS вас ввести неправильным регулярным выражением (то есть O (2 ^ n) или O (n!) Или любым другим), и самый простой способ предотвратить это может быть чтобы сократить время ожидания страницы.

...