Node.js Security
Node.js security is mostly about treating every input as hostile on a single shared thread: keep code and data separate, never let user input choose paths, prototypes or destinations, and assume dependencies can be malicious.
Key points
- 1
Use parameterized queries,
execFilewith argument arrays (plus a--separator), and schema validation that enforces types, so input can never become code, operators or options. - 2
Prototype pollution comes from merging untrusted objects: block
__proto__,constructorandprototype, useMaporObject.create(null), and check permissions withObject.hasOwn. - 3
Resolve and contain file paths with
path.resolvepluspath.relative; a stringstartsWith(base)check is fooled by sibling folders. - 4
Anything CPU-bound on the event loop, such as a catastrophic regex or a huge JSON body, blocks every user. Limit input sizes and timeouts, and use linear-time regex engines for untrusted patterns.
- 5
SSRF defences must check the resolved IP (including IPv4-mapped IPv6), pin the connection to it, and re-check redirects.
- 6
Use
crypto.randomBytes/randomUUIDfor tokens, argon2id or bcrypt for passwords, AES-GCM with a fresh IV for encryption, andtimingSafeEqualon equal-length buffers. - 7
Supply-chain risk is real: lockfiles plus
npm ci,--ignore-scripts, scoped internal packages, provenance checks and few dependencies.npm auditonly knows reported issues.
Common traps
JSON.stringifyoutput is not HTML-safe:</script>inside a string ends an inline script tag.--disable-protoand the vm module are defence in depth at best; neither stops a determined attacker on its own.SameSite=Laxstill sends cookies on top-level GET navigations, so state-changing GET endpoints stay forgeable.
Test yourself on Node.js Security
Ten questions, with the answer and explanation after each one.