A dependency-free Go CLI for assessing Node2Shell exposure (CVE-2026-111497) from advertised Node.js runtime versions. Requires Go 1.22+.
Once this repository is published on GitHub:
go install -v github.com/tal7aouy/node2shell-scanner/cmd/node2shell@latest
node2shell -u https://example.comAdd $(go env GOPATH)/bin to your PATH if GOBIN is unset.
Or build from the project directory:
go build -o node2shell ./cmd/node2shell
./node2shell -u https://example.comnode2shell -u https://example.com/api
node2shell -l hosts.txt -t 8 -timeout 20s -o results.json
node2shell -u https://example.com -H 'Authorization: Bearer YOUR_TOKEN'
cat hosts.txt | node2shell -l -Target files contain one URL per line. Blank lines, comments beginning with #,
and duplicate normalized URLs are skipped. Use on authorized systems.
| Flag | Purpose | Default |
|---|---|---|
-u URL |
Single target; choose either -u or -l |
— |
-l FILE |
Target list, or - for stdin |
— |
-o FILE |
Save every result as JSON; requires a new file | — |
-t N |
Concurrent targets, 1–256 | 4 |
-timeout DURATION |
Request timeout, such as 20s |
15s |
-H 'Name: Value' |
Request header; repeatable | — |
-k |
Disable TLS verification | Off |
-h |
Show help | — |
One GET request checks Server and X-Powered-By for an explicit Node.js
version. Root URLs use /; supplied paths and queries are preserved. HTTPS is
the default, TLS verification is enabled, and redirects are not followed.
No malformed Brotli, crash probes, or RCE payloads are sent.
Node.js published fixes on October 21, 2026 in 22.23.4, 24.22.1, and 26.12.1. Exposure requires an application to decompress attacker-controlled Brotli data. See the official advisory.
| Result | Meaning |
|---|---|
POTENTIALLY_VULNERABLE |
A supported runtime banner predates the fix. Verify vendor patches and Brotli usage. |
PATCHED_VERSION |
The banner meets the fixed-version threshold. Verify the running runtime. |
UNKNOWN |
Missing, ambiguous, vendor, prerelease, older, or unverified runtime version. |
ERROR |
Request failed or target was invalid. |
If a result is UNKNOWN, its message includes the HTTP status and the next
verification step. For redirects, provide the destination URL explicitly. If a
request times out, increase -timeout and check connectivity.
An Express header alone is insufficient. Banners may be stale and vendor fixes
may be backported. This check cannot establish vulnerability, confirm RCE, or
assess applications that fetch and decode untrusted Brotli responses.
Reports exclude headers and body content, but include target URLs and query
parameters. Avoid secrets in URLs. Files use mode 0600, never overwrite an
existing file, and list results in input order. Responses are capped at 1 MiB
after decompression, and headers at 1 MiB.
Exit codes: 0 for all patched-version results, 1 for any potential finding,
2 for incomplete assessments or CLI/report errors, 130 for interruption.
Potential findings take precedence over unknown results; inspect each entry.
docker build -t node2shell-scanner .
docker run --rm node2shell-scanner -u https://example.com
docker run --rm -v "$PWD:/data" -w /data node2shell-scanner -l hosts.txt -o results.jsonThe container runs as UID 65532. Mounted output directories must be writable
by that user.
go test -race ./...
go vet ./...Tests use in-memory HTTP fixtures and cover version boundaries, redirects, response limits, request headers, URL validation, transport failures, and CLI validation. No external targets are contacted.
GitHub Actions
checks formatting, static
analysis, race-enabled tests, coverage, builds, CLI installation, and Docker.
It covers stable Go on Linux, macOS, and Windows, plus Go 1.22 on Linux. .gitattributes enforces LF line endings on all platforms.
Docker CI also verifies that the container runs as a non-root user.