На каких языках это отверстие безопасности для использования пользовательского регулярного выражения? - программирование
Подтвердить что ты не робот

На каких языках это отверстие безопасности для использования пользовательского регулярного выражения?

Изменить: tchrist сообщил мне, что мои первоначальные обвинения в незащищенности Perl необоснованны. Тем не менее, вопрос все еще стоит.

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

4b9b3361

Ответ 1

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

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

Для получения дополнительной информации прочитайте эту страницу: http://www.regular-expressions.info/catastrophic.html

Ответ 2

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

use re "eval";

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

Часы:

% perl -le '$x = "(?{ die 'naughty' })"; "aaa" =~ /$x/'
Eval-group not allowed at runtime, use re 'eval' in regex m/(?{ die naughty })/ at -e line 1.
Exit 255

% perl -Mre=eval -le '$x = "(?{ die 'naughty' })"; "aaa" =~ /$x/'
naughty at (re_eval 1) line 1.
Exit 255

Ответ 3

Обычно это динамические языки с установкой eval, которые имеют тенденцию выполнять код из регулярных выражений. В статических языках (т.е. Для тех, для которых требуется отдельный этап компиляции), как правило, невозможно выполнить код, который не был скомпилирован, поэтому оценка кода из регулярного выражения невозможна.

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

Ответ 4

1) Уязвимости обнаруживаются в библиотеках регулярных выражений, таких как переполнение буфера которое влияет на Webkit, и позволяет любому злоумышленнику получить удаленный запуск кода с помощью доступ к библиотеке регулярных выражений из javascript.

2) Это условие DoS в С#.

3) Пользовательское регулярное выражение может быть для php из-за модификаторов. Добавление модификатора /e увеличивает совпадение. В этом случае система будет eval().

preg_replace("/.*/e","system('echo /etc/passwd')");

Или в виде уязвимости:

preg_replace($_GET['regex'],$_GET['check']);

Ответ 5

Регулярные выражения - это язык программирования. Я не думаю, что они достаточно Тьюринга, но они достаточно близки, что позволяет вашим пользователям вводить их на свой веб-сайт. Это позволяет другим людям запускать код на вашем сервере. QED, да, это дыра в безопасности.

Возможно, вам удастся уйти с возможностью подмножества любого языка регулярного выражения, который вы хотите использовать, присваивать белый список определенному набору конструктов, чтобы сделать его не достаточно большим, чтобы потнуть отверстие... другие люди уже упоминали о возможных суждениях гнездования и *. Насколько вы готовы позволить людям загружать ваш сервер, зависит от вас. Лично мне было бы удобно, если бы у них был один оператор SQL CONTAINS и, возможно, "BETWEEN()".:)

Ответ 6

Я подозреваю, что рубин позволил бы /#{system("rm -rf really_important_directory")}/ - это то, о чем вы беспокоитесь?

Ответ 7

AFAIK, вы можете сделать это безопасно в С#: вы можете снабдить строку регулярного выражения конструктору Regex, и если он не сможет проанализировать, он будет метать. Я не уверен в других.