Хук regex представляет собой детерминированный движок проверки безопасности регулярных выражений, который запускает специализация regex, и вы можете запускать его сами. Он работает в двух режимах одной командой: сканирование проверяет кодовую базу на шаблоны, уязвимые к ReDoS или собираемые во время выполнения, а проверка оценивает отдельный шаблон, который вы ему передаете.
Сканирование кодовой базы
Без флага хук сканирует весь проект. --dir ограничивает сканирование директорией, --file одним файлом. Оба флага можно повторять и сочетать в одном отчете, и каждый файл указывается один раз, даже если его охватывает несколько целей.
- Весь проект
- Директория
- Один файл
- Несколько целей
- С лимитом
npx lagune read regex
npx lagune read regex --dir src/services
npx lagune read regex --file bin/import.pl
npx lagune read regex --dir core --dir workers --file Sources/App/Router.swift
--limit задает порог ReDoS для сканирования (по умолчанию 25), тот же лимит, что принимает режим проверки. Чем ниже лимит, тем строже проверка.
npx lagune read regex --dir src/services --limit 15
Вывод представляет собой простой текст, заголовки которого объясняют, как читать каждый раздел. Раздел показывается, только если в нем есть находки.
Vulnerable regular expressions found:
cmd/server/main.go
([a-z]+)+$ (exponential, search)
Dynamically built regular expressions (review manually by simulating a constructed regex):
app/payments.php
crates/parser/lexer.rs
lib/validate.py
Static regex wrapped in a constructor (use a literal instead):
config/token.rb
Если ничего не найдено, выводится одна строка.
npx lagune read regex --dir src/clean
# => no unsafe patterns found
Как читать разделы
| Раздел | Значение |
|---|---|
Vulnerable regular expressions found | Шаблоны, уязвимые к ReDoS, сгруппированные по файлам: каждый шаблон с отступом под своим файлом, а за ним в скобках причина, по которой он небезопасен, и, если есть, его область действия и флаги. Каждая строка небезопасна, поэтому вердикт не повторяется. |
Regular expressions the analysis could not settle (review manually) | Шаблоны, которые анализ не смог оценить в пределах своего лимита работы, в том же виде. |
Dynamically built regular expressions (review manually by simulating a constructed regex) | Файлы, которые собирают регулярное выражение из переменной, конкатенации или интерполяции. |
Static regex wrapped in a constructor (use a literal instead) | Файлы, которые передают обычный строковый литерал в конструктор регулярного выражения там, где литерал регулярного выражения проще и не требует компиляции во время выполнения. |
Первый раздел содержит находки безопасности. Второй и третий сами по себе находками не являются: они указывают на код, который статическая проверка не может оценить, поэтому требуют, чтобы его прочитал человек. Четвертый служит подсказкой для ясности кода, а не находкой безопасности.
Параметры CLI
| Параметр | Значение | Описание |
|---|---|---|
--pattern | исходный текст регулярного выражения | Проверяет один шаблон. Повторите, чтобы проверить несколько, по одному вердикту на шаблон, по порядку. |
--flags | флаги регулярного выражения | Проверяет каждый --pattern с этими флагами, например im. Действует только в режиме проверки. |
--dir | директория | Ограничивает сканирование директорией. Можно повторять и сочетать с --file. |
--file | файл | Ограничивает сканирование одним файлом. Можно повторять и сочетать с --dir. |
--limit | неотрицательное целое число | Задает лимит повторений ReDoS (по умолчанию 25). Действует в обоих режимах. Чем ниже лимит, тем строже проверка. |
Без параметров хук сканирует весь проект. --pattern включает режим проверки и не сочетается с --dir или --file.
Поддерживаемые языки
Сканирование читает эти языки, определяя их по расширению файла, каждый по его собственным правилам, поэтому шаблон из одного языка никогда не проверяется по правилам другого. Все остальное пропускается, а не сканируется по неправильным правилам.
| # | Язык | Расширения |
|---|---|---|
| 1 | JavaScript / TypeScript | .js, .jsx, .mjs, .cjs, .ts, .tsx, .mts, .cts, .astro, .vue, .svelte, .marko, .riot |
| 2 | Python | .py, .pyi |
| 3 | Ruby | .rb |
| 4 | Go | .go |
| 5 | PHP | .php |
| 6 | Rust | .rs |
| 7 | Java | .java |
| 8 | C# | .cs |
| 9 | C | .c, .h |
| 10 | C++ | .cc, .cpp, .cxx, .hpp, .hh, .hxx |
| 11 | Kotlin | .kt, .kts |
| 12 | Swift | .swift |
| 13 | Scala | .scala, .sc |
| 14 | Dart | .dart |
| 15 | PowerShell | .ps1, .psm1, .psd1 |
| 16 | Elixir | .ex, .exs |
| 17 | Objective-C | .m, .mm |
| 18 | R | .r |
| 19 | Julia | .jl |
| 20 | Clojure | .clj, .cljs, .cljc, .edn |
| 21 | Crystal | .cr |
| 22 | Nim | .nim, .nims |
| 23 | V | .v |
| 24 | D | .d |
| 25 | Perl | .pl, .pm |
Хук читает исходный код как текст, поэтому не может оценить шаблон, собранный во время выполнения, а шаблон, разбитый на несколько строк, спрятанный за псевдонимом или записанный в нераспознаваемой форме, может проскользнуть. Считайте разделы надежной отправной точкой, а не полной инвентаризацией, и продолжайте читать код там, куда они не дотягиваются.
Проверка отдельного шаблона
Передайте --pattern с исходным текстом шаблона, чтобы оценить его. Хук выводит одно слово: safe, unsafe, undetermined, если анализ достиг своего лимита работы, не успев оценить шаблон, или invalid regex. Повторите --pattern, чтобы оценить несколько сразу, по одному вердикту на шаблон, по порядку.
- Один шаблон
- Несколько шаблонов
- С флагами
- С лимитом
npx lagune read regex --pattern '(a+)+$'
# => unsafe
npx lagune read regex --pattern '^[a-z0-9_]{3,20}$'
# => safe
npx lagune read regex --pattern '(a+)+$' --pattern '^[a-z]+$'
# => unsafe
# => safe
--flags проверяет каждый --pattern в вызове с теми флагами, с которыми он выполняется, поскольку флаг меняет, какие символы совпадают с шаблоном.
npx lagune read regex --pattern '^(?:a|A)+$'
# => safe
npx lagune read regex --pattern '^(?:a|A)+$' --flags 'i'
# => unsafe
--limit задает лимит повторений (по умолчанию 25) и действует для каждого --pattern в вызове. Чем ниже лимит, тем строже проверка.
npx lagune read regex --pattern 'a?a?a?' --limit 2
# => unsafe
Каждый шаблон передается как значение флага и никогда не подставляется в команду. Значение с кавычками или обратными кавычками остается инертным и не может внедриться в оболочку. Всегда заключайте шаблон в одинарные кавычки, чтобы оболочка не раскрыла его раньше.
Это тот же движок, который запускает специализация regex: сканирование открывает проход по ReDoS, а проверка подтверждает найденный им шаблон.
Частые вопросы
Выполните npx lagune read regex --pattern '<pattern>'. Команда возвращает safe, unsafe, undetermined или invalid regex.
Запустите хук regex в режиме сканирования по кодовой базе. Он сообщает о шаблонах, уязвимых к ReDoS, на 25 поддерживаемых языках.
