Как я могу безопасно использовать регулярные выражения из пользовательского ввода? - PullRequest
13 голосов
/ 29 января 2010

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

$regex = eval { qr/$text/ };
if (my $error = $@) { 
   # mangle $error to extract user-facing message

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

Есть ли потенциальные угрозы безопасности при выполнении этого - какой-то странный ввод, который может привести к выполнению произвольного кода? (Помимо уязвимостей переполнения буфера в механизмах регулярных выражений, таких как CVE-2007-5116). Если да, есть ли способы их смягчения?

Есть ли лучший способ сделать это? Любые модули Perl, которые помогают абстрагировать операции преобразования пользовательского ввода в регулярные выражения (например, извлечение сообщений об ошибках ... или предоставление модификаторов, таких как /i, которые мне здесь не нужны, но было бы неплохо)? Я искал CPAN и не нашел много обещающего, но развлекаюсь тем, что что-то упустил.

Ответы [ 5 ]

6 голосов
/ 29 января 2010

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

Регулярные выражения - Механизм регулярных выражений Perl - это так называемый NFA (недетерминированный конечный автомат), который, среди прочего, означает, что он может довольно легко потреблять большое количество времени и пространства, если регулярное выражение может совпадать несколькими способами. Тщательная обработка регулярных выражений может помочь, но довольно часто мало что можно сделать (книга «Освоение регулярных выражений»). Выражение "требуется чтение, см. Perlfaq2). Недостаток свободного места проявляется в том, что Perl исчерпывает память.

4 голосов
/ 18 мая 2015

Об этом обсуждается в Монастыре .

TLDR: use re::engine::RE2 -strict => 1;

Убедитесь, что добавили -strict => 1 в оператор использования, или re :: engine :: RE2 вернется к Perl.

Ниже приводится цитата Пола Ванкадия (младшего), владельца проекта на GitHub :

RE2 был разработан и реализован с явной целью обеспечения возможности обработки регулярных выражений ненадежных пользователей без риска. Одна из основных гарантий заключается в том, что время совпадения линейно по длине входной строки. Он также был написан с учетом производственных проблем: синтаксический анализатор, компилятор и механизмы выполнения ограничивают использование своей памяти, работая в настраиваемом бюджете - изящно отказывая при исчерпании - и избегая переполнения стека, избегая рекурсии.

Подводя итог важным пунктам:

  • По умолчанию это безопасно от выполнения произвольного кода, но добавьте "no re 'eval';" предотвратить PERL5OPT или что-нибудь еще от установки его на вас. Я не уверен, что это мешает.

  • Использование подпроцесса (fork) с BSD :: Resource (даже в Linux) для ограничения памяти и уничтожения дочернего элемента через некоторое время.

4 голосов
/ 29 января 2010

С помощью конструкции (?{ code }) пользовательский ввод может использоваться для выполнения произвольного кода. Смотрите пример в perlre # code и где написано

local $cnt = $cnt + 1,

заменить его на выражение

system("rm -rf /home/fennec"); print "Ha ha.\n";

(На самом деле, не делайте этого.)

3 голосов
/ 29 января 2010

лучший способ - не давать пользователям слишком много привилегий. Предоставьте интерфейс, достаточный для того, чтобы пользователи могли делать то, что они хотят. (как банкомат с только кнопками для различных опций, нет необходимости ввода с клавиатуры). Конечно, если вам нужно, чтобы пользователь ввел ввод, затем предоставьте текстовое поле, а затем на бэкэнде используйте Perl для обработки запроса (например, санитарная обработка и т. Д.). Мотивом того, чтобы позволить вашим пользователям вводить регулярные выражения, является поиск строковых шаблонов, верно? Тогда в этом случае самый простой и безопасный способ - попросить их ввести только строку. Затем на заднем плане вы используете регулярное выражение Perl для его поиска. Есть ли другие веские причины, по которым пользователь может самостоятельно вводить регулярные выражения?

1 голос
/ 29 января 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...