es-lint-security помечает небезопасное регулярное выражение
У меня есть регулярное выражение, которое выглядит так /^[A-Za-z.,'-]([A-Za-z.,' -]*[A-Za-z.,'-])?$/
Я недавно добавил плагин eslint-config-security и пометил приведенное выше регулярное выражение как небезопасное из-за detect-unsafe-regex
править.
Там не сказано, почему это небезопасно.
Может кто-нибудь сказать мне, почему это небезопасно и что я могу сделать, чтобы это исправить?
Он запускает этот пакет
2 ответа
Детали: Наконец-то есть время, поэтому я объясню, что здесь происходит. Причина - катастрофический откат назад. Я возьму пример из блога:
Вы делаете что-то вроде этого (х + х +)+ у при этом ([A-Za-z.,' -]*[A-Za-z.,'-])
х + х + мог бы быть ограничен х +, но в вашем случае разница между х невелика. Таким образом, решение для вас заключается в использовании ([A-Za-z.,' -]* ?)
Таким образом, механизм регулярных выражений не сломает систему.
Что происходит, изложено ниже из блога:
Рассмотрим регулярное выражение (x + x +)+ y. Давайте посмотрим, что произойдет, когда вы примените это регулярное выражение к xxxxxxxxxxy. Первый х + будет соответствовать всем 10 х символов. Второй х + терпит неудачу. Первый х + затем возвращается к 9 совпадениям, а второй забирает оставшиеся х. Группа сейчас подобрана один раз. Группа повторяется, но терпит неудачу при первом x +. Когда y терпит неудачу, механизм regex возвращается. У группы есть одна итерация, в которую она может вернуться. Второй х + соответствует только одному х, поэтому он не может вернуться. Но первый х + может дать один х. Второй х + быстро соответствует хх. У группы снова есть одна итерация, следующая неудача завершается, а у - неудача. Когда у вас происходит сбой, двигатель regex возвращается. У группы есть одна итерация, в которую она может вернуться. Второй х + соответствует только одному х, поэтому он не может вернуться. Но первый х + может дать один х. Второй х + быстро соответствует хх. У группы снова есть одна итерация, следующая неудача завершается, а у - неудача. Откат назад, второй х + теперь имеет одну позицию возврата, уменьшая себя до соответствия х. Группа пробует вторую итерацию. Первый х + совпадает, но второй застрял в конце строки. Снова возвращаясь, первый x + в первой итерации группы сокращается до 7 символов. Второй х + соответствует ххх. Если нет, то второй x + уменьшается до xx, а затем x.
Если вы попробуете это регулярное выражение в строке 10 x в отладчике RegexBuddy, потребуется 2558 шагов, чтобы выяснить, что в конце отсутствует y. Для строки 11x требуется 5118 шагов. Для 12 требуется 10238 шагов. Ясно, что здесь мы имеем экспоненциальную сложность O(2^n). В 21x отладчик выдает 2,8 миллиона шагов, диагностируя серьезный случай катастрофического возврата.
Движки Regex (например,.NET) будут работать вечно, в то время как другие будут аварийно завершать работу с переполнением стека (например, Perl до версии 5.10). Переполнение стека особенно неприятно в Windows, поскольку оно приводит к исчезновению вашего приложения без следа и объяснений.
Похоже, что плагин использует слово unsafe, чтобы продемонстрировать регулярное выражение, которое может вызвать катастрофический откат:
обнаружить потенциально катастрофические регулярные выражения экспоненциального времени, ограничив высоту звезды до 1
и ваше регулярное выражение может вызвать его, что вы можете увидеть здесь в действии. Пожалуйста, прочитайте этот ответ, чтобы лучше понять эту проблему.