
Semgrep rules that flag header-trust auth bypass patterns (CVE-2025-29927 class). Companion to bk-security.github.io.
A small Semgrep rule pack that flags code making authentication, authorization, or trust decisions based on HTTP request headers an attacker controls.
The canonical example of the vulnerability class is
CVE-2025-29927: Next.js
trusted the x-middleware-subrequest header to decide whether middleware ran,
and any inbound request that supplied a crafted value could skip middleware
entirely. The same shape recurs across frameworks and ecosystems.
This pack ships rules for two language families and three sub-classes of the bug. It is intended as a code-review aid, not a fully-tuned CI gate. The rules prefer recall over precision and are best run interactively, with a human making the call on each finding.
For a longer write-up of the vulnerability class and the design choices behind this pack, see bk-security.github.io.
| Rule | Language | Severity | Catches |
|---|---|---|---|
nodejs-header-flag-auth-bypass | JS / TS | Warning | Reads of headers whose name suggests internal-protocol or auth-bypass use (x-internal, x-bypass-auth, x-middleware-subrequest, x-admin-override, x-impersonate, etc.) |
nodejs-header-as-identity | JS / TS | Warning | Reads of headers conventionally used to carry user identity (x-forwarded-user, x-authenticated-user, x-remote-user, etc.) |
nodejs-forwarded-for-trust | JS / TS | Info | Reads of x-forwarded-for, x-real-ip, and similar source-IP headers that are commonly trusted for security decisions |
python-header-flag-auth-bypass | Python | Warning | Same as the Node.js variant, including Django-style request.META["HTTP_X_*"] access |
python-header-as-identity | Python | Warning | Same as the Node.js variant, Python-flavored |
python-forwarded-for-trust | Python | Info | Same as the Node.js variant, Python-flavored |
Install Semgrep:
pip install semgrep
Run the pack against a target:
semgrep --config /path/to/auth-header-trust-rules/rules /path/to/target
Or run a single rule:
semgrep --config /path/to/auth-header-trust-rules/rules/nodejs/header-flag-auth-bypass.yaml /path/to/target
Validate the rules against the bundled fixtures:
semgrep --test --config rules/ tests/
Expected output:
6/6: ✓ All tests passed
The rules match on a curated list of header names known to be dangerous when trusted. They will catch the common cases. They will not catch:
getInternalFlag(req) that reads x-some-novel-name will pass the rules.x-internal-*, x-trust-*, and x-bypass-*, but novel names
will slip through.When extending the pack for a specific codebase, the highest-value additions
are usually framework-specific helper-function patterns. If a codebase has a
isInternalRequest(req) helper, the rule that catches it is one line of YAML.
rules/<lang>/<name>.yaml.tests/<lang>/<name>.<ext> with positive
examples annotated # ruleid: <rule-id> and negative examples annotated
# ok: <rule-id>.semgrep --test --config rules/ tests/. The new rule and fixture will
be picked up automatically; tests must pass before submitting a change.MIT.
Bruce Kang. Source for the companion blog post lives at bk-security.github.io.