Node.js / Express Penetration Testing: Prototype Pollution, npm Supply-Chain & JavaScript Backend Security
Node.js dominates the modern JavaScript backend ecosystem, but its dynamic nature and massive npm ecosystem create unique attack surfaces: prototype pollution, RCE via deserialization, SSRF via HTTP clients (axios, node-fetch), and supply-chain risks tied to transitive dependencies. Matproof Sentinel runs targeted Node.js / Express pentests with proof-of-exploit and audit-ready reports from €149.
Why Node.js requires specific pentest attention
The Node.js ecosystem has experienced major incidents in 2023-2024 that illustrate the model's structural risks. The HTTP/2 Rapid Reset vulnerability (CVE-2023-44487, CVSS 7.5) enabled massive DDoS attacks against exposed Node.js servers — Cloudflare detected attacks of 398 million requests/second. The jsonwebtoken flaw (CVE-2022-23529) affected virtually all Node.js applications using the most widely deployed JWT library. The recent CVE-2024-39338 in axios exposed hundreds of thousands of applications to SSRF via malformed relative URLs. Beyond specific CVEs, Node.js patterns such as dynamic property manipulation via JSON.parse and extensive use of the spread operator create unique vectors for prototype pollution potentially leading to RCE.
- CVE-2023-44487 (HTTP/2 Rapid Reset, CVSS 7.5): massive DDoS against exposed Node.js HTTP/2 servers — Cloudflare, Google, and AWS reported 398M requests/sec attacks in 2023.
- CVE-2022-23529 (jsonwebtoken): JWT signature validation bypass in the most widely used library for Node.js authentication — affects ≈ 9 million weekly npm downloads.
- CVE-2024-39338 (axios SSRF): malformed relative URLs enable SSRF attacks against internal endpoints (AWS metadata, internal services) via Node.js's most widely used HTTP client (60M+ weekly downloads).
- Prototype pollution: Node.js-specific attack pattern exploited in popular libraries (lodash, jQuery, async) to escalate to RCE — found in 13% of Node.js applications scanned by Snyk in 2024.
- npm supply-chain risks: 1.2 million npm packages, ~75% with transitive dependencies; notable incidents: event-stream (2018), ua-parser-js (2021), color.js / faker.js (2022).
- Express.js, the most deployed Node.js framework, doesn't include default protections against CSRF, XSS, or injection — the responsibility for every security middleware rests on the developer.
- For fintechs under DORA Art. 24 or SaaS under NIS2, documented Node.js pentest is standard compliance.
What we specifically test in a Node.js / Express application
- Prototype pollution: property injection into Object.prototype via JSON.parse, body-parser, qs.parse, or Object.assign — escalation paths to RCE via gadget chains (lodash.template, kibana-style).
- jsonwebtoken vulnerabilities: « none » algorithm accepted, HS256/RS256 algorithm confusion, jwt-decode used for verification (anti-pattern), missing 'exp' and 'iat' validation.
- npm supply chain: complete dependency audit (npm audit --production), packages with suspicious post-install scripts, dependencies with unpatched CVEs in package-lock.json.
- SSRF via HTTP clients: axios (CVE-2024-39338), node-fetch, got, request — URL validation bypass via relative URLs, IPv6, Unicode encoding, DNS rebinding requests.
- Header injection (CRLF injection): carriage return injection in HTTP headers via user parameters — Express up to 4.18.2 vulnerable per CVE-2022-24999.
- HTTP/2 configuration: exposure to CVE-2023-44487 (Rapid Reset) if HTTP/2 enabled without stream-level rate-limiting; verification of settings_max_concurrent_streams protections.
- NoSQL injection via mongoose / mongodb: $ne, $gt, $where operators in user queries; authentication bypass via injected $or/$and; arbitrary $set manipulation operators.
- Insecure deserialization: use of node-serialize (notoriously vulnerable), eval() with user data, vm.runInNewContext without sandbox, child_process.exec with user input.
- Express configuration: authentication middleware in wrong order, helmet absent (security headers), express-rate-limit not configured, cookie-parser without secret, express-session with in-memory store in production.
- Sensitive data logging: Winston / Pino configured to log full Authorization headers, request bodies containing passwords, query parameters with tokens.
Sample finding
Exploitable Prototype Pollution to RCE in body-parser with lodash gadget chain
The Express application uses body-parser to process JSON requests without restrictive configuration. Testing reveals an attacker can send a JSON payload containing the « __proto__ » key that pollutes Object.prototype globally. For example, POST /api/profile with body {"__proto__": {"polluted": true}} causes all JavaScript objects to subsequently inherit the 'polluted' property. The application also uses lodash.template with a partially user-controlled template in the report generation function, which creates a classic exploitation chain (gadget chain): prototype pollution → lodash.template → RCE. The test demonstrates arbitrary code execution with the Node.js process privileges.
Fix: Immediate update to patched versions: body-parser ≥ 1.20.3, lodash ≥ 4.17.21. Configure body-parser with the option { strict: true, reviver: function (key, value) { if (key === '__proto__' || key === 'constructor') return undefined; return value; } } to block sensitive keys. Replace lodash.template with sandboxed templating libraries (handlebars with strict mode, or ESLint with no-prototype-builtins rules). Implement Object.freeze(Object.prototype) at application startup to block any root-level pollution. Set up a strict CSP policy with « unsafe-eval » disabled. Enable strict ECMAScript mode via 'use strict' in all modules.
Reference: CVE-2022-24999 (qs prototype pollution) · CWE-1321 (Prototype Pollution) · OWASP A08:2021 (Software and Data Integrity Failures) · Snyk Research: Prototype Pollution Attacks in Node.js · NIST SP 800-218 (SSDF)
Node.js pentest options compared
| — | Free scan | Matproof Sentinel | Traditional consultancy |
|---|---|---|---|
| Automated scan engine | ✓ (3-min preview) | ✓ Full scan | ✗ Manual only |
| OWASP Top 10 coverage | Partial | ✓ Complete | ✓ Complete |
| Proof-of-exploit evidence | ✗ | ✓ Per finding | ✓ Per finding |
| Regulatory mapping (DORA/NIS2/ISO 27001) | ✗ | ✓ Automated | ✓ Manual |
| Audit-ready PDF report | ✗ | ✓ Instant | ✓ 2–4 weeks delivery |
| Continuous / recurring scans | ✗ | ✓ Per deploy | ✗ Annual engagement |
| Time to first result | ~3 min | ~30 min full scan | 2–4 weeks |
| Price | €0 | From €149 | €8,000–€25,000 |
| Source code review (SAST) | ✗ | ✓ On Growth plan | ✓ Scoped engagement |
| API testing (REST/GraphQL) | ✗ | ✓ Automated | ✓ Manual |
Node.js pentest packages
- 1 full pentest scan
- AI-prioritized findings with CVSS 3.1
- Proof-of-exploit per finding
- Audit-ready PDF report
- Regulatory mapping (DORA, NIS2, ISO 27001)
- Unlimited scans (up to 3 domains)
- Continuous monitoring
- CI/CD integration (GitHub, GitLab)
- All regulatory mappings
- Priority support
- Unlimited scans + domains
- Authenticated / White-Box testing
- API & cloud infrastructure tests
- Dedicated security account manager
- 24h SLA response time
Frequently asked questions about Node.js / Express pentest
What's the difference between a Node.js pentest and a standard npm-audit?
npm audit identifies known CVEs in installed dependencies via the GitHub Advisory database. A Node.js pentest goes beyond: we test runtime-specific patterns (prototype pollution, SSRF via HTTP clients, deserialization), Express middleware configuration, and demonstrate actual exploitability with proof-of-exploit. npm audit reports 'there's a CVE.' The pentest demonstrates 'here's how it's exploited in your code.'
How do you audit the npm supply chain?
Our process includes four layers: (1) static analysis of package-lock.json to identify all transitive dependencies (often 800-2000+ per project); (2) cross-reference with NVD, GitHub Advisory, and Snyk Database for unpatched CVEs; (3) detection of suspicious packages (typosquatting, post-install scripts, recent packages with low downloads); (4) pinning and migration recommendations to maintained alternatives. We provide a complete supply-chain risk mapping in the final report.
My Node.js application uses NestJS / Fastify / Koa instead of Express. Does the pentest apply?
Yes. We cover the entire Node.js ecosystem: NestJS, Fastify, Koa, Hapi, AdonisJS, RedwoodJS, and Next.js (API routes side). Vulnerability classes are largely common (prototype pollution, deserialization, SSRF, supply-chain), but we adapt test vectors to each framework.
Can the pentest test our Node.js GraphQL APIs (Apollo, GraphQL Yoga)?
Yes. Node.js GraphQL APIs require specific tests beyond traditional OWASP API Top 10: query depth limiting (DoS via nested queries), introspection in production (schema leakage), batch query attacks, and resolver-level authorization.
How do you handle Node.js tests on serverless architectures (Lambda, Vercel, Cloudflare Workers)?
We test serverless Node.js functions like any HTTP endpoint, with special attention to specifics: cold-start side-channel timing, environment variable leakage via stack traces, IAM role privilege escalation (Lambda), unintended state sharing between invocations.
How long does a complete Node.js pentest take?
The full automated scan (covering the 7 main Node.js vulnerability classes) takes about 60 minutes for a typical Express application. For more complex applications (Node.js microservices, GraphQL): 2-4 hours. Audit-ready report within 24 hours.
Go deeper — related blog articles
Protect your Node.js application now
First scan in 3 minutes, complete Node.js pentest in 60 minutes with proof-of-exploit for every finding. Audit-ready DORA / NIS2 / ISO 27001 report from €149.
Start free scan