2014-01-05 4 views
3

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

Например, если у меня есть код ниже:

<?php 

if(isset($_POST['regex'])) { 
    preg_match($_POST['regex'], $_POST['match'], $matches); 
    var_dump($matches); 
} 

?> 
<form action="" method="post"> 
<input type="text" name="regex"> 
<textarea name="match"></textarea> 
<input type="submit"> 
</form> 

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

Я уже узнал о «злых регулярных выражениях», однако, независимо от того, что я пытаюсь использовать на своем компьютере, они, похоже, работают нормально, см. Ниже.

PHP

<?php 
php > preg_match('/^((ab)*)+$/', 'ababab', $matches);var_dump($matches); 
array(3) { 
    [0] => 
    string(6) "ababab" 
    [1] => 
    string(0) "" 
    [2] => 
    string(2) "ab" 
} 
php > preg_match('/^((ab)*)+$/', 'abababa', $matches);var_dump($matches); 
array(0) { 
} 

JavaScript

phantomjs> /^((ab)*)+$/g.exec('ababab'); 
{ 
    "0": "ababab", 
    "1": "ababab", 
    "2": "ab", 
    "index": 0, 
    "input": "ababab" 
} 
phantomjs> /^((ab)*)+$/g.exec('abababa'); 
null 

Это приводит меня к мысли, что PHP и JavaScript имеют отказоустойчивый механизм злыми регулярных выражений. Исходя из этого, я бы хотел, чтобы другие языки имели схожие функции.

Это правильное предположение?

И, наконец, для любых или всех языков, которые могут быть вредными, существуют ли способы убедиться, что регулярные выражения не нанесли урон?

+0

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

+1

С модификатором 'e' (в PHP) что-то будет оценено (чего вы, вероятно, не хотите), см. [Руководство] (http://www.php.net/manual/en/reference.pcre.pattern .modifiers.php) – kero

+0

@SLaks, когда вы говорите «длинные строки», любая идея о том, как долго мы говорим? –

ответ

4

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

Используя ваш пример ^((ab)*)+$, вам нужно немного больше, неисправного вход, чтобы вызвать катастрофический откат вступили в силу: "ababababababababababababababababababababababd".

  • Для версии PHP, вызов preg_last_error должен вернуть PREG_BACKTRACK_LIMIT_ERROR.
  • Для версии JS код выше не вызывает катастрофического возврата в Firefox 26, и браузер возвращает false. В Chrome 31.0.1650.63 m и Internet Explorer 11 можно наблюдать катастрофическое обратное отслеживание.

В зависимости от API языка/библиотеки API может предоставить возможность ограничить количество попыток обратного отслеживания или установить тайм-аут операции; настоятельно рекомендуется установить лимит, чтобы предотвратить DoS на вашем сервере.

  • PCRE по умолчанию, чтобы остановить после того, как 10 миллионов попыток отслеживания источников, а число может быть сконфигурировано.
  • .NETRegex класс поставляется с API, чтобы ограничить время, необходимое для согласования.

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

Если только в спецификации регулярных выражений двигателя включает в себя требование, чтобы предотвратить катастрофические откаты (например PCRE имеет по умолчанию возвратов предела), вы не должны полагаться на поведении конкретной реализации (например, в случае Firefox, как описан выше) ,

Смежные вопросы