🟒

node2shell

Security Auditor

Probes Node.js for the node2shell Brotli request-body flaw

Security
200 credits
Per check
~30 seconds
Average runtime
Active
Status

Runs on your verified domains

node2shell probes a site for weaknesses, so it only runs on domains your organization has proven it owns, by email, a DNS record or a file on the site. That keeps it from being pointed at someone else's site.

How it works

  1. Control requests β€” sends five one-byte POSTs that vary the Brotli encoding and content type (malformed Brotli with no content type, valid empty Brotli as JSON, malformed Brotli as JSON, an unsupported encoding) to learn how the endpoint answers valid route traffic versus malformed input.

  2. Response classes β€” only continues when the controls establish a distinct route-response class and malformed-Brotli class; otherwise it reports no signal without ever uploading the probe.

  3. Probe β€” streams the 23,068,764-byte Brotli body as application/json with Expect: 100-continue, then repeats the valid control to confirm the endpoint stayed stable.

  4. Verdict β€” the host is vulnerable only when the full probe reaches the route-response class, the malformed class is distinct, and the final control still matches the route class. The scanner returns one verdict (VULNERABLE, NO SIGNAL, INCONCLUSIVE or ERROR), which this auditor maps to a single result.

Preferences

KeyTypeDefaultDescription
timeoutSecondsinteger20Per-request timeout for the scanner, 5–120. The scan sends five one-byte control requests plus one 23 MB probe in sequence, so keep it well under two minutes. An out-of-range or invalid value falls back to 20.

What this auditor validates

  • Whether the route handler decompresses an attacker-controlled Brotli request body without limit (the core of CVE-2026-111497), by comparing the 23 MB probe's response class against the learned route and malformed-Brotli classes.

  • It inspects only the audited page for a block (HTTP 403 / 429 / Cloudflare challenge); the probe and controls are part of the audited request, not separate paths.

Every row maps to one checkRule* method and one CheckCode. CheckCode suffixes use status ranges: 100 information, 200–299 success, 300–399 warning, 400–499 fail, 500–599 error.

CheckCodeStatusWhen it firesRecommendationWhy it matters
37A-Node2ShellAuditor-100INFORMATIONAlways. Records the CVE this auditor probes for.β€” (recommendation is null; nothing for the site to change)β€”
37A-Node2ShellAuditor-200SUCCESSVerdict NO SIGNAL: the 23 MB probe did not reach the route response class, so nothing indicates the flaw.β€”β€”
37A-Node2ShellAuditor-300WARNINGVerdict INCONCLUSIVE: a control request failed, so no firm verdict was reached.Re-run the audit; if a WAF or proxy rejected the probe, test the Node.js origin directly so its exposure to CVE-2026-111497 can be confirmed.An inconclusive probe leaves the CVE status unknown, so the server may still be exposed; treat it as unverified rather than safe and re-run or test the origin directly.
37A-Node2ShellAuditor-400FAILVerdict VULNERABLE: the 23 MB Brotli probe reached the learned route response class.Update the affected Node.js component on {host} (the HTTP server or the Brotli request-body decompression middleware) to a release that fixes CVE-2026-111497, or stop decompressing Brotli request bodies and cap the decompressed size, then restart the service.An unauthenticated request can make the Node.js process decompress an attacker-controlled Brotli body on the route handler, so a crafted upload can exhaust memory and take the service down (denial of service), and the memory corruption behind it can open the door to worse.
37A-Node2ShellAuditor-500ERRORVerdict ERROR: the scan could not run against the target (could not connect, resolve or normalize the URL).Make {url} reachable over HTTP(S) and re-run the audit.β€”
37A-Node2ShellAuditor-590ERRORThe audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page.Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See https://www.37audits.com/bot.While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported.

Output Documentation

StatusDescriptionTest logic
SUCCESSNot affectedThe probe did not reach the route response class β€” no signal (200).
WARNINGCould not confirmThe scan was inconclusive β€” a control request failed (300).
FAILVulnerableThe 23 MB Brotli probe reached the learned route response class (400).
ERRORThe auditor could not checkThe scan could not run against the target (500); the site blocked 37AuditsBot (590).
INFORMATIONReferenceThe CVE this auditor probes for (100); never changes the result.

Risks and Considerations

This probe uploads a 23 MB body

  • On a vulnerable server the probe is the condition that exhausts the process; on any server it uploads 23 MB. Only run this against sites you own or are authorized to test β€” which is why it is gated on domain verification and is off for anonymous previews. The Expect: 100-continue header lets a proxy reject the size before the body is sent.

A clean result is not a guarantee

  • NO SIGNAL means the probe did not cross into the route response class. It is reported as a pass, but it is not proof of safety: confirm the affected component is patched.

  • INCONCLUSIVE means a WAF, proxy or server error stopped the scan from reaching a verdict. The server may still be exposed β€” re-run, or test the Node.js origin directly.

Verify findings with a human

  • This auditor wraps Assetnote's node2shell-scanner and infers the verdict from the server's responses, so a result can be wrong in either direction: a WAF, proxy or load balancer can absorb the probe and look like a pass, and an unrelated response change can look like a crossing. Before you act on a FAIL β€” or rely on a SUCCESS β€” have a person confirm it against the host (check the running component versions and the server logs for the probe requests).

Why it matters

  • The flaw lets an unauthenticated request make the Node.js process decompress an attacker-controlled Brotli body, so a crafted upload can exhaust memory and take a site down (denial of service).

  • The memory corruption behind the crash raises the risk of worse outcomes than a crash, so patching promptly matters.

This documentation is built and hosted on Mintlify, a developer documentation platform.

Source: docs.37audits.com

Ready to start auditing?

Add this auditor to your monitoring setup and start identifying issues on your websites today.

Β© 2026 37 Audits. All rights reserved. Audit your websites with confidence.

Supported by

Made with ❀️ in Floripa