psf-sentry-nextjs-check(8)
@sentry/nextjs tunnelRoute middleware bypass: read-only checker (v1)
CVE-2026-114139 (GHSA-mchm-gjx6-7h55)
If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation
The tunnelRoute option of the Sentry SDK for Next.js sends browser events to a path
on your own server (for example /monitoring), where a rewrite forwards them to
Sentry. To stop your middleware rejecting those envelope requests, the SDK makes
the webpack build skip middleware for them. The skip is WIDER than the rewrite: it
covers every path under the tunnel path, while the rewrite serves only the exact
tunnel path with valid query parameters. A request in that gap reaches your
application and your middleware never runs on it. Skipping middleware grants no
privileges by itself. CVSS 9.1 (v4.0).
Affected: @sentry/nextjs 9.36.0 up to 9.47.2, 10.0.0-alpha.0 up to 10.75.2,
11.0.0-alpha.0 up to 11.0.0-rc.1
Fixed: 9.47.2, 10.75.2 and 11.0.0-rc.1 (all exist on the npm registry)
EXPLOITATION NEEDS ALL FOUR OF THESE AT ONCE:
1. tunnelRoute is set (a string path, or true);
2. the app is built with webpack (Turbopack builds are not affected);
3. one of your routes resolves under the tunnel path;
4. your middleware is the ONLY authorization control for that route.
The vendor's own workaround: set tunnelRoute to a path no route of yours can resolve
under, or remove the option.
This script is read-only. It finds Next.js projects, reads the @sentry/nextjs version
from package-lock.json, npm-shrinkwrap.json, yarn.lock, pnpm-lock.yaml, bun.lock and
installed node_modules, then reads next.config.* for tunnelRoute, guesses the bundler
from the build script and the Next.js version, and looks for routes that collide with
the tunnel path. Conditions 2 and 3 are judged from file and script contents; condition 4 cannot be seen from
outside the application, so review it yourself.
Usage:
./sentry-nextjs-check.sh [command] [DIR ...]
check (default) scan DIR (default /var/www /srv /opt /home). Exit 0 = nothing
exposed, 1 = an affected version with tunnelRoute on a webpack
build, or a configuration that could not be read.
version print the script version.
Containers: with no directory argument the check also reads the project files it needs from
running docker and podman containers (SCAN_CONTAINERS=1, the default; 0 skips them), through a
read-only probe, and judges them like host projects. The copies are temporary: a path shown as
.../docker_NAME/PATH is the PATH inside the container NAME.The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.