Hooks

cors hook: Audit CORS origins

Scan source for a bypassable CORS origin allowlist, or score a single origin value for over-permissive access, from the command line.

The cors hook is the deterministic engine behind the http-request specialization, and you can run it yourself. It works in two modes from one command: a scan that sweeps source for a bypassable origin allowlist (a host-validation regex an attacker host slips past), and a score that rates a single CORS origin value as wildcard, null, or safe.

Scan a codebase​

With no flag it scans the whole project.

npx lagune read cors

It lists each bypassable allowlist under one header, grouped by file. A host validator whose .+/.* sits in the authority segment before the trusted-host suffix (^https?://.+\.trusted\.com) lets an attacker host like your-site.com.attacker.com slip past.

Origin-allowlist patterns with a greedy wildcard (bypassable, review):

internal/auth/origin.go
^https?://.+\.trusted\.com

This is a review lead, not a closed finding: whether the regex gates a real trust decision is undecidable from the text, so a scan never changes the exit code. Read each and confirm the allowlist compares by full equality. When nothing is found, it prints a single line.

npx lagune read cors --dir src/clean
# => no bypassable origin allowlist found

Score an origin​

Pass each origin with --origin. The hook prints one word per origin and exits non-zero on any wildcard or null.

npx lagune read cors --origin '*' # => wildcard
npx lagune read cors --origin 'null' # => null
npx lagune read cors --origin 'https://app.example.com' # => safe
VerdictMeaning
safeNot *, null, or a *-glob. It does not guarantee a well-formed origin.
wildcard*, a subdomain/host/port glob: any site (or a wide set) may read the response.
nullThe null origin, which sandboxed iframes and redirects can forge.

Only safe is an allow, and --origin is a value oracle: it judges the value, not the handler, so confirm the handler with the http-request specialization.

CLI options​

OptionValueDescription
--originan originScore one origin value. Repeat to score several, one per line.
--dira directoryScope a scan to a directory. Repeats and combines with --file.
--filea fileScope a scan to a single file. Repeats and combines with --dir.

With no option it scans the whole project. --origin is the score mode and cannot be combined with --dir or --file.

Choose what it scans​

It leaves out what Git ignores. To leave out more, or to scan what Git ignores, give cors settings of its own:

npx lagune write add --ignore test/fixtures --checker cors
{
"checkers": {
"cors": { "gitignore": false, "ignore": ["test/fixtures"] }
}
}

Configure the hooks covers every setting.

What it does not cover

The scan reads the bypassable-regex shape, and --origin scores origin values. Two source-level patterns stay out of reach: reflection of the request's Origin (the server echoes the incoming Origin back, or pairs it with credentials), and a permissive endsWith/substring allowlist. Recognize them in the code and treat them as the http-request specialization describes.

Frequently Asked Questions

Sandboxed iframes and some redirects send Origin: null, so an allowlist that trusts null grants those contexts read access. The cors hook flags it alongside the wildcard.

Run npx lagune read cors over the codebase. It flags a host-validation regex whose greedy wildcard sits before the trusted suffix, so an attacker host like your-site.com.attacker.com slips past.