Мені відомо про відмову в сервісі регулярних виразів (ReDoS). Чи є якийсь розумний спосіб дозволити користувачам створювати власні регулярні вирази, гарантуючи, що вони не подають експоненціально повільний шаблон?
Мені відомо про відмову в сервісі регулярних виразів (ReDoS). Чи є якийсь розумний спосіб дозволити користувачам створювати власні регулярні вирази, гарантуючи, що вони не подають експоненціально повільний шаблон?
Відповіді:
Проблема з регулярними виразами полягає не в самому регулярному вираженні, а в тому, що двигун регулярних виразів має всі види "зручних" функцій, таких як зворотний трекінг. Тому використання двигуна-регексу без цих функцій уникає.
Регулярні вирази концепції інформатики завжди можуть бути узгоджені в лінійному часі після їх складання на машину з кінцевим станом. Тому двигун, заснований на стані машини, не може використовуватися для ReDoS. Однак необхідні державні машини можуть стати досить великими на патологічних прикладах. Але обмеження доступної пам'яті, як правило, простіше, ніж обмеження доступного часу на обчислення.
Двигун RE2 був розроблений спеціально для боротьби з ненадійними регексами і був розроблений для виконання лінійного часу.
Ще одна альтернатива - складання регексів самостійно із спрощеного позначення. Наприклад, ви можете дозволити користувачам використовувати глобальні шаблони (наприклад *.txt
). Потім ви можете проаналізувати це таким чином, що запобігає зворотному відстеженню, наприклад, забороняючи вкладення та використовуючи лише жадібні квантори. Для багатьох випадків використання спрощене позначення візерунка є цілком достатнім.
Аналіз регулярного виразу, щоб побачити, чи буде він повільним чи ні, без того, що сам аналіз стає повільним , означає вирішення проблеми зупинки. Іншими словами, знайти правильне і повне рішення неможливо .
Можна, звичайно, знайти рішення , яке є правильним і в комплекті. Наприклад, ви можете працювати з обмеженим білим списком функцій, які безпечно використовувати (наприклад, класи класів символів так, повторення немає ...). Це дозволить вам пропустити безліч некритичних регексів, відкинути всі критичні та (помилково) відхилити деякі, які добре, але занадто складні, щоб автоматично виявитись безпечними.
Як автор повторного аналізу для проекту lazarus, я б сказав, що немає жодного способу зрозуміти для будь-якого заданого регулярного виразу, які ресурси він буде споживати в заданому тексті.
Не витрачаючи однакових ресурсів, я маю на увазі (принаймні, в значенні big-O).
Тож найкращий підхід - запустити повторний аналізатор в окрему нитку і вбити її після таймауту.
На додаток до інших відповідей, рішенням може бути також скручування власної бібліотеки регулярних виразів, яка дозволяє виконувати інструментацію виконання під час виконання, і таким чином надавати засоби для вбивства виконання на півдорозі, якщо дотримуються деякі критерії.
Аналогічно, ви можете запустити реджекси на інший потік і вбити нитки, якщо вони займуть занадто довго.