regex 훅은 regex 전문 지식이 실행하는 결정론적 정규식 안전성 엔진이며, 직접 실행할 수도 있습니다. 명령어 하나로 두 가지 모드를 쓸 수 있습니다: scan 모드는 ReDoS에 취약한 패턴과 런타임에 만들어지는 패턴이 있는지 코드베이스를 스캔하고, check 모드는 건네받은 패턴 하나에 점수를 매깁니다.
코드베이스 스캔
플래그를 지정하지 않으면 프로젝트 전체를 스캔합니다. --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)을 정하며, check 모드에서 쓰는 한도와 같습니다. 한도가 낮을수록 더 엄격합니다.
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 같은 플래그로 검사. check 모드에만 적용 |
--dir | 디렉터리 | 스캔 범위를 디렉터리로 한정. 반복 지정 가능, --file 옵션과 함께 사용 가능 |
--file | 파일 | 스캔 범위를 단일 파일로 한정. 반복 지정 가능, --dir 옵션과 함께 사용 가능 |
--limit | 0 이상의 정수 | ReDoS 반복 한도 설정(기본값 25). 두 모드 모두에 적용. 한도가 낮을수록 더 엄격 |
옵션을 지정하지 않으면 프로젝트 전체를 스캔합니다. --pattern 옵션은 check 모드이며, --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 전문 지식이 실행하는 것과 같은 엔진입니다. scan 모드로 ReDoS 점검을 시작하고, check 모드로 스캔에서 드러난 패턴을 확인합니다.
자주 묻는 질문
npx lagune read regex --pattern '<pattern>' 명령어를 실행하세요. safe, unsafe, undetermined, invalid regex 중 하나를 반환합니다.
regex 훅을 scan 모드로 코드베이스 전체에 실행하세요. 지원하는 25개 언어에서 ReDoS에 취약한 패턴을 보고합니다.
