Skip to content

Add active scan script for CVE-2025-29927 (Next.js middleware authentication bypass) - #525

Open
comradezephyr wants to merge 1 commit into
zaproxy:mainfrom
comradezephyr:patch-1
Open

comradezephyr wants to merge 1 commit into
zaproxy:mainfrom
comradezephyr:patch-1

Conversation

@comradezephyr

Copy link
Copy Markdown

Summary

Adds an active scan script that detects CVE-2025-29927, a critical (CVSS 9.1)
authorization bypass in Next.js. Next.js uses the x-middleware-subrequest
request header to identify its own internal subrequests and, in vulnerable
versions, trusts it without verifying that the request originated internally.
Supplying the header causes the application's middleware to be skipped
entirely, bypassing any authentication, authorization or redirect logic
implemented there.

Fixed in Next.js 12.3.5, 13.5.9, 14.2.25 and 15.2.3.

What the script does

  • Only tests GET nodes, and only continues when the baseline response looks
    gated by middleware (301/302/303/307/308, 401 or 403). Resources returning
    200 are skipped, since public and protected responses cannot be
    distinguished.
  • Repeats the request with each known x-middleware-subrequest value
    (middleware x5, src/middleware x5, middleware, src/middleware,
    pages/_middleware). The x5 values are needed for Next.js 13.2 and later,
    where the middleware module name must appear five times
    (MAX_RECURSION_DEPTH).
  • Confirms a bypass only when the gate is gone: a 200 response that differs
    from the baseline and does not look like a login page. 5xx responses are
    ignored.
  • Raises High risk / Medium confidence when Next.js response headers are
    present, downgrading to Low confidence when they are not (they are trivial
    to hide), so weaker findings do not pollute high-confidence reports.
  • Follows the getMetadata() / ScanRuleMetadata.fromYaml pattern already
    used by active/SSTI.js and active/OpenModelContextProtocolServer.js.

Metadata: id: 100046, CWE-287 (Improper Authentication), WASC-1,
OWASP Top 10 2021 A01 / 2017 A02 alert tags, status: alpha.

How it was tested

  • node --check on the script: pass
  • ./gradlew spotlessCheck (same check CI runs): pass
  • Repo test suite VerifyScripts (parses every script with GraalJS):
    182 tests, 182 successful, 0 failed, including
    TEST-DONE active\CVE202529927.js -> SUCCESSFUL
  • Behavioural harness against scripted mock servers covering 13 scenarios
    (vulnerable, patched, SPA shell, SSO gateway, public page, 401 gate,
    same-size response, 5xx, hidden Next.js headers, POST skip, de-duplication,
    scan() no-op, metadata): 43 checks, 0 failed
  • getMetadata() YAML validated with SnakeYAML (the parser ZAP uses):
    all 14 keys and references parsed correctly

I have not yet run a live end-to-end scan inside ZAP against a real Next.js
deployment; the verification above is at the script level. Happy to run it
against a lab target and report results if that would help.

References

Notes

This is my first contribution to ZAP. Feedback on style and conventions is
welcome. I chose 100046 as the scan rule ID after checking the IDs already
used by the community scripts (highest existing is 100045); happy to change
it if another is preferred.

While preparing this I noticed that ./gradlew check fails on Windows
because VerifyScripts.readFiles() filters the classpath with
endsWith("/scripts") while Gradle passes a path with backslashes on
Windows. It fails before reading any script file. CI runs on Linux so it is
unaffected. I did not touch that file; mentioning it in case it is worth a
separate issue.

…ication bypass)

This script implements an active scan rule for CVE-2025-29927, targeting Next.js middleware authentication bypass vulnerabilities. It sends requests with specific headers to check if the middleware can be bypassed, raising alerts when vulnerabilities are confirmed.

Signed-off-by: Zephyr <149247976+comradezephyr@users.noreply.github.com>
@comradezephyr

Copy link
Copy Markdown
Author

Note: I have not added a CHANGELOG.md entry yet. Happy to add one under : )
[Unreleased] → Added if that is required before merge.

@psiinon

psiinon commented Sep 20, 2026

Copy link
Copy Markdown
Member

Logo
Checkmarx One – Scan Summary & Details629522d0-5596-4c98-8a4b-bb5b0cfa5402


New Issues (12 out of 12) Checkmarx found the following issues in this Pull Request

Severity: 2 High · 4 Medium · 6 Low

# Severity Issue Source File / Package Checkmarx Insight
1 HIGH CVE-2026-68497 Maven-com.fasterxml.jackson.core:jackson-databind-2.17.0
detailsRecommended version: 2.18.10
Description: jackson-databind binds a JSON string to a javax.xml.datatype.Duration or javax.xml.datatype.XMLGregorianCalendar field by passing the raw string ve...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
2 HIGH Last User Is 'root' /docker-wrapper: 10
detailsLeaving the last user as root can cause security risks. Change to another user after running the commands that need privileges
3 MEDIUM CVE-2026-19032 Maven-com.fasterxml.jackson.core:jackson-databind-2.17.0
detailsRecommended version: 2.18.10
Description: jackson-databind's deserializer for `java.nio.file.Path` resolves an attacker-supplied URI without restricting the URI scheme. In `JDKFromStringDes...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
4 MEDIUM Hardcoded_Password_in_Connection_String other/api/sdlc-integration/core/scan_module/scan.py: 219
detailsThe application contains hardcoded connection details, "PASS: ", at line 219 of /other/api/sdlc-integration/core/scan_module/scan.py. This conn...
Attack Vector
5 MEDIUM Unchecked_Input_for_Loop_Condition standalone/load_context_from_burp.py: 29
detailsMethod at line 29 of /standalone/load_context_from_burp.py obtains user input from load - the range of this value is not validated, and is ev...
Attack Vector
6 MEDIUM Use_of_Broken_or_Risky_Cryptographic_Algorithm payloadgenerator/associated_fields.py: 34
detailsIn , the application protects sensitive data using a cryptographic algorithm, hexdigest, that is considered weak or even trivially broken, in /payl...
Attack Vector
7 LOW Filtering_Sensitive_Logs other/api/sdlc-integration/core/scan_module/scan.py: 218
detailsThe application logs various user events, and in method  writes sensitive user details to debug, in /other/api/sdlc-integration/core/scan_module/...
Attack Vector
8 LOW Filtering_Sensitive_Logs other/api/sdlc-integration/core/scan_module/scan.py: 243
detailsThe application logs various user events, and in method  writes sensitive user details to debug, in /other/api/sdlc-integration/core/scan_module/...
Attack Vector
9 LOW MAINTAINER Instruction Being Used /docker-wrapper: 3
detailsThe MAINTAINER instruction sets the Author field of the generated images. The LABEL instruction is a much more flexible version of this and you sh...
10 LOW Unpinned Actions Full Length Commit SHA /codeql.yml: 31
detailsPinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA help...
11 LOW Unpinned Actions Full Length Commit SHA /codeql.yml: 34
detailsPinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA help...
12 LOW Unpinned Actions Full Length Commit SHA /codeql.yml: 35
detailsPinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA help...

Use @Checkmarx to take action directly from this PR:

  • Rescan the PR

Try it: @Checkmarx how can you help? · @Checkmarx rescan this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants