---
title: "Next.js Known CVE Scanner"
canonical: https://trickest.com/library/nextjs-security-scanner
description: "Fingerprint Next.js hosts, safely probe two advisories, and version-classify CVE-2025-29927 plus React2Shell (CVE-2025-55182)."
---

# Next.js Known CVE Scanner

## Overview

Different Next.js advisories demand different evidence. A version match can
prioritize a host, but no safe remote confirm exists for every flaw. This
workflow takes a file of web servers, fingerprints Next.js with
[httpx](/tools/httpx), and
returns a separate, evidence-qualified finding for each of four advisories,
including React2Shell (CVE-2025-55182). CVE-2026-75604 walks `..%5C` toward a
canary and compares a control. GHSA-2xp9-vwfh-vxw4 probes `/_next/image` with a
local asset, a remote URL, an `.avif` name, and two JPEG widths. A fetch is not
marked as remote code execution. CVE-2025-29927 and CVE-2025-55182 are
version-only: the run never sends the middleware bypass header and never sends
a Flight body. Each node writes its own findings. The last node merges them
into `report.json`, one `final_report.jsonl` line per advisory,
`findings.jsonl`, and `owner.csv`. Most other Next.js advisories have no safe
remote check and stay off the graph. Attach the host file and check these hosts
from [exposure management](/use-cases/exposure-management).

## Pipeline

1. Read the host file (`hosts`, URLs, or JSONL) and write one URL per line for [httpx](/tools/httpx).
2. [httpx](/tools/httpx) live-checks each host and records title, tech, web
   server, and status.
3. `fingerprint` maps Next.js: printed version, Windows server signal, `buildId`,
   Pages via `/_next/data`, App via RSC headers, and the cache paths
   CVE-2026-75604 will walk.
4. `cve-2026-75604` walks `..%5C` toward a canary and compares a control. It
   does not read `server-reference-manifest.json` and does not forge a Server
   Action.
5. `ghsa-2xp9-vwfh-vxw4` classifies `/_next/image`. It never sends crafted AVIF
   bytes and never marks a fetch as RCE.
6. `cve-2025-29927` is version-only. It never sends a middleware bypass header.
7. `cve-2025-55182` is version-only. It never sends a Flight body.
8. `report` merges the four streams into `findings.jsonl`, `report.json`, one
   `final_report.jsonl` line per advisory, and `owner.csv`. Unknown version is
   never clean on a version-gated CVE.

## Inputs

- **Host file.** A file of web servers, one per line: hostname, `host:port`,
  `http(s)` URL, or JSONL with `url` / `host`. Point it at Next.js apps you
  are authorised to test. Blanks and `#` comments are skipped. The node keeps
  the first 200 hosts. If no file is attached, the default is `example.com`.

## Outputs

- **findings.jsonl.** One operator row per host per advisory: `cve`, `advisory`,
  `target_url`, `is_nextjs`, observed version, `vulnerable`, `confirmed`,
  `action`, `check_detail`, and evidence.
- **report.json.** Title, the four advisory IDs, generated timestamp, overall summary,
  `by_advisory` counts, and the full findings list.
- **final_report.jsonl.** One manager line per advisory (`total_targets`,
  `vulnerable`, `not_vulnerable`, `inconclusive`, `errors`,
  `vulnerability_rate`, `patch`).
- **owner.csv.** The same rows flattened for the people who own the hosts.

## Integrations

- [httpx](/tools/httpx) for the initial live-host and Next.js fingerprint pass.
- HTTP for the advisory-specific canary, image optimizer, and version checks.

## Sample output

Illustrative, in the record shape the workflow emits. Real runs name live hosts,
so the targets here are documentation domains.

```jsonl
{"cve": "CVE-2026-75604", "advisory": "GHSA-p293-qw3h-jr36", "target_url": "https://app.example.com", "is_nextjs": true, "observed_version": "16.2.6", "vulnerable": true, "confirmed": true, "error": null, "action": "patch to 15.5.24 or 16.3.3", "check_detail": "traversal=diverged; pages_and_app=true", "evidence": "traversal diverged on Windows with Pages and App", "windows_signal": "IIS", "pages_and_app": true, "optimizer": "present"}
{"cve": "GHSA-2xp9-vwfh-vxw4", "advisory": "GHSA-2xp9-vwfh-vxw4", "target_url": "https://app.example.com", "is_nextjs": true, "observed_version": "16.2.6", "vulnerable": false, "confirmed": false, "error": null, "action": "go look", "check_detail": "optimizer fetches_remote; a fetch is not RCE for this GHSA", "evidence": "optimizer fetches_remote; a fetch is not RCE for this GHSA", "windows_signal": "IIS", "pages_and_app": true, "optimizer": "fetches_remote"}
{"cve": "CVE-2026-75604", "advisory": "GHSA-p293-qw3h-jr36", "target_url": "https://www.example.org", "is_nextjs": true, "observed_version": "16.3.3", "vulnerable": false, "confirmed": false, "error": null, "action": "leave the train", "check_detail": "traversal=no-diverge; pages_and_app=false", "evidence": "16.3.3 is patched and the check did not confirm", "windows_signal": "", "pages_and_app": false, "optimizer": "locked"}
{"cve": "GHSA-2xp9-vwfh-vxw4", "advisory": "GHSA-2xp9-vwfh-vxw4", "target_url": "https://www.example.org", "is_nextjs": true, "observed_version": "16.3.3", "vulnerable": false, "confirmed": false, "error": null, "action": "leave the train", "check_detail": "16.3.3 is patched (AVIF optimization disabled)", "evidence": "16.3.3 is patched (AVIF optimization disabled)", "windows_signal": "", "pages_and_app": false, "optimizer": "locked"}
```

The final report is one line per advisory:

```json
{"cve": "CVE-2026-75604", "total_targets": 2, "findings": 2, "vulnerable": 1, "not_vulnerable": 1, "inconclusive": 0, "errors": 0, "vulnerability_rate": 50.0, "patch": "15.5.24 (15.x) or 16.3.3 (16.x)"}
{"cve": "GHSA-2xp9-vwfh-vxw4", "total_targets": 2, "findings": 2, "vulnerable": 0, "not_vulnerable": 1, "inconclusive": 1, "errors": 0, "vulnerability_rate": 0.0, "patch": "15.5.24 (15.x) or 16.3.3 (16.x)"}
{"cve": "CVE-2025-29927", "total_targets": 2, "findings": 2, "vulnerable": 0, "not_vulnerable": 1, "inconclusive": 1, "errors": 0, "vulnerability_rate": 0.0, "patch": "12.3.5 / 13.5.9 / 14.2.25 / 15.2.3"}
{"cve": "CVE-2025-55182", "total_targets": 2, "findings": 2, "vulnerable": 0, "not_vulnerable": 1, "inconclusive": 1, "errors": 0, "vulnerability_rate": 0.0, "patch": "15.0.5+ / 16.0.7"}
```

`report.json` wraps those findings with `title`, `cve` (the four IDs), `generated`,
`summary`, `by_advisory`, and the full `findings` array.

## FAQ

### Which Next.js builds does this flag as in range?

CVE-2026-75604: 13.4 through the last 15.x before 15.5.24, and 16.0 through the
last 16.x before 16.3.3. GHSA-2xp9-vwfh-vxw4 starts earlier, at 10.0.0, and uses
the same patched builds. CVE-2025-29927 and CVE-2025-55182 use their own floors
and stay version-only. Each finding is scored on its own advisory. A printed
version in range is not enough on its own, and a blank version is never written
as clean. A canary or rc tag is also never written as clean.

### When does CVE-2026-75604 not apply even if the version is in range?

The Windows cache bug needs a Windows filesystem and both the Pages router
(`/_next/data`) and the App router answering on the same host. Linux and macOS
hosts are not this CVE. Missing an IIS banner is not proof of Linux: that row
is go look. The check still sends the `%5C` pair so you can see whether the
separator was evaluated. The AVIF finding on the same host is independent: an
open optimizer does not mark the Windows row vulnerable.

### What does go look mean when the host prints no version?

Next.js was fingerprinted and the version string was blank. That advisory's
row is not clean. If the Windows check already confirmed a traversal on
Windows with Pages and App, that row is patch. A remote or `.avif` fetch on
the GHSA node is go look, not patch: a fetch is not remote code execution.
Otherwise `action` is go look: fetch the lockfile or the deployed image tag
before you close the ticket.

### Does GHSA-2xp9-vwfh-vxw4 send a crafted AVIF?

No. It asks `/_next/image` for a local asset, a remote HTTPS URL, a URL that
ends in `.avif`, and two widths of a public JPEG. A fetch or a resize is
recorded on `optimizer`. A crafted overflow AVIF is never sent, so a 200 here
is not remote code execution and the row is never marked vulnerable.

### How is this different from the public CVE-2026-75604 PoC?

The public PoC walks `..%5C` out of a Pages ISR and App cache path, reads the
Server Action manifest, forges an action, and runs a command. This workflow
keeps only the first step's shape: the same walk, aimed at a canary filename,
compared to a control. A diverge is the confirm. The run does not read the
manifest, does not take a key, and does not send a Server Action.

## Related workflows

- [WordPress Pre-Auth RCE (CVE-2026-63030)](/library/wordpress-wp2shell-pre-auth-rce).
  Reach for this instead when the product is WordPress and you need a confirmed
  injection chain, not a Next.js cache or image check.
- [SPA Endpoint and Parameter Map](/library/spa-endpoint-and-parameter-map).
  Reach for this instead when you want the JS bundle's routes and parameters,
  not a yes or no on these two Next.js paths.
- [Exposed Database Scanner](/library/exposed-database-scanner). Reach for this
  instead when the question is an open data store on the same fleet, not the
  Next.js security scanner.

---
_Markdown source of https://trickest.com/library/nextjs-security-scanner._
