Hooks

regex hook

Sweep a codebase for ReDoS-prone regex, or score a single pattern, from the command line.

regex hook

The regex hook is the deterministic regex-safety engine the regex sub-skill runs, and you can run it yourself. It works in two modes from one command: a scan that sweeps a codebase for ReDoS-prone and runtime-built patterns, and a check that scores a single pattern you hand it.

Scan a codebase

With no flag it scans the whole project. -d scopes the scan to a directory, -f to a single file. Both repeat and combine into one report, each file listed once even when more than one target covers it.

node ./.lagune/hooks/regex.mjs

The output is raw text whose headers say how to read each section. A section is shown only when it has findings.

Vulnerable regular expressions found:

cmd/server/main.go
([a-z]+)+$

Dynamically built regular expressions (review manually):

app/payments.php
crates/parser/lexer.rs
lib/validate.py

Static regex wrapped in a constructor (use a literal instead):

config/token.rb

When nothing is found, it prints a single line.

node ./.lagune/hooks/regex.mjs -d src/clean
# => no unsafe patterns found

How to read the sections

SectionMeaning
Vulnerable regular expressions foundReDoS-prone patterns, grouped by file with each pattern indented beneath. Every line is unsafe, so the verdict is not repeated.
Dynamically built regular expressions (review manually)Files that build a regex from a variable, a concatenation, or an interpolation. Not a finding on its own: read each by hand.
Static regex wrapped in a constructor (use a literal instead)Files that pass a plain string literal to a regex constructor where a regex literal is simpler and skips a runtime compile.

The first section is a security finding. The second is a pointer to code a static check cannot judge, so it asks for a human read. The third is a clarity hint, not a security finding.

CLI options

OptionAliasValueDescription
--pattern-pa regex sourceCheck one pattern. Repeat to check several, one verdict per pattern, in order.
--dir-da directoryScope a scan to a directory. Repeats and combines with -f.
--file-fa fileScope a scan to a single file. Repeats and combines with -d.
--limit-la non-negative integerSet the ReDoS repetition limit (default 25). Applies to both modes. A lower limit is stricter.

With no option it scans the whole project. -p is the check mode and cannot be combined with -d or -f.

Supported languages

The scan reads these languages, keyed by file extension, each by its own rules so a pattern from one is never tested against another. Everything else is skipped rather than scanned with the wrong rules.

#LanguageExtensions
1JavaScript / TypeScript.js, .jsx, .mjs, .cjs, .ts, .tsx, .mts, .cts, .astro, .vue, .svelte, .marko, .riot
2Python.py, .pyi
3Ruby.rb
4Go.go
5PHP.php
6Rust.rs
7Java.java
8C#.cs
9C.c, .h
10C++.cc, .cpp, .cxx, .hpp, .hh, .hxx
11Kotlin.kt, .kts
12Swift.swift
13Scala.scala, .sc
14Dart.dart
15PowerShell.ps1, .psm1, .psd1
16Elixir.ex, .exs
17Objective-C.m, .mm
18R.r
19Julia.jl
20Clojure.clj, .cljs, .cljc, .edn
21Crystal.cr
22Nim.nim, .nims
23V.v
24D.d
25Perl.pl, .pm
Best-effort, not exhaustive

It reads source as text, so it cannot judge a pattern assembled at runtime, and a pattern spread across lines, hidden behind an alias, or written in a form it does not recognize can slip past. Treat the three sections as a strong starting point, not a complete inventory, and keep reading the code for what they cannot reach.

Check a single pattern

Pass -p with the pattern's source to score it. The hook prints one word: safe, unsafe, or invalid regex. Repeat -p to score several at once, one verdict per pattern, in order.

node ./.lagune/hooks/regex.mjs -p '(a+)+$'
# => unsafe

node ./.lagune/hooks/regex.mjs -p '^[a-z0-9_]{3,20}$'
# => safe
Why a quoted argument

Each pattern is passed as a flag value, never interpolated into the command. A value with quotes or backticks stays inert and cannot inject into the shell. Always wrap the pattern in single quotes so your shell does not expand it first.

tip

This is the same engine the regex sub-skill runs: the scan opens a ReDoS pass, the check confirms a pattern it surfaces.

Copyright © 2026-present Weslley Araújo and contributors. SDH: Lagune is under the MIT License. Please check the Security Policy.

All product names, trademarks, and registered trademarks mentioned are the property of their respective owners and are used for identification purposes only.