Contents
“One forgotten eval() sank a fintech’s $2 M seed round. Let’s make sure it doesn’t happen to you.”
Nodejs makes shipping features fast; sometimes too fast. In 2025, public CVE data shows SQL/NoSQL injection is still the #1 flaw in Nodejs applications, followed closely by prototype pollution and malicious dependencies. Below you’ll find runnable code, real-world fixes, and a copy-paste checklist so you can push secure code without slowing CI/CD.

Why Nodejs Apps Get Pwned in 2025
Dependency sprawl: the average Express project pulls 1 200+ packages.
Event-loop blocking: a single ReDoS regex can spin CPU to 100 %.
Typosquatting: packages like electorn (note the typo) still rack up 20 k weekly downloads before takedown.
The 7 Deadly Vulnerabilities & Code-Level Fixes
SQL/NoSQL Injection
Bad
|
|
Good
|
|
Use parameterized queries (pg, mysql2, mongodb all support them). Validate IDs with Joi.number().integer().positive().
Prototype Pollution
Vulnerable
|
|
Fixed
|
|
Add Object.freeze(Object.prototype) during bootstrap to prevent prototype tampering.
XSS & CSRF
XSS fix
|
|
CSRF fix
|
|
Send token in res.locals._csrf and validate on every state-changing request.
ReDoS & DoS
ReDoS-safe regex
|
|
Rate-limiting
|
|
Malicious Dependencies
npm config set ignore-scripts truenpx lockfile-lint --path package-lock.json --allowed-hosts npmnpm audit --audit-level moderatein CI.
Sensitive Data Exposure
- Store secrets in
.env, never commit to Git. - Hash passwords with
bcrypt.hash(password, 12). - Add Helmet in one line:
|
|
Headers added include Strict-Transport-Security, X-Content-Type-Options, Content-Security-Policy, etc.
SSRF & DNS Rebinding
Allow-list IPs
|
|
Disable inspector in prod: node --inspect=0.0.0.0:0 is never safe.
Nodejs Security Checklist 2025 (Copy-Paste Ready)
| # | Task | CLI / Snippet |
|---|---|---|
| 1 | Use Nodejs 20+ | nvm use 20 |
| 2 | Enable --experimental-permission |
node --experimental-permission --allow-fs-read=* index.js |
| 3 | Parameterize all queries | pool.query('SELECT * FROM users WHERE id = $1', [id]) |
| 4 | Freeze prototypes | Object.freeze(Object.prototype) |
| 5 | Add Helmet | app.use(helmet()) |
| 6 | Rate-limit sensitive routes | express-rate-limit |
| 7 | Audit deps | npm audit --audit-level moderate |
| 8 | Lint lockfile | npx lockfile-lint |
| 9 | Sanitize HTML | DOMPurify.sanitize() |
| 10 | Hash passwords | bcrypt.hash(password, 12) |
| 11 | Validate env | require('dotenv-safe').config() |
| 12 | Secure CI | npm ci --ignore-scripts |
Save as SECURITY.md in repo root.
Tooling Deep-Dive
| Tool | Type | Example |
|---|---|---|
| eslint-plugin-security | Static linting | npm i -D eslint-plugin-security "extends": ["plugin:security/recommended"] |
| Snyk Code | SAST | npx snyk test |
| CodeQL | GitHub-native | .github/workflows/codeql.yml |
Helmet vs express-rate-limit
| Concern | Helmet | express-rate-limit |
|---|---|---|
| XSS | ✔ CSP header | ✖ |
| Brute-force login | ✖ | ✔ |
| ReDoS mitigation | ✖ | ✔ |
| Lines of code | 1 | 3-5 |
Use both; they’re complementary.
Automating Security in CI/CD
.github/workflows/security.yml
|
|
FAQ
Q: How to prevent SQL injection in Nodejs?
A: Always use parameterized queries ($1, $2 placeholders) and validate inputs with Joi or zod.
Q: Nodejs prototype pollution fix with example?
A: Freeze Object.prototype on startup and sanitize deep merges as shown above.
Q: Best Nodejs security linter?
A: eslint-plugin-security for quick local checks; Snyk Code or CodeQL for deeper SAST in CI.
Conclusion & Next Step
Security doesn’t have to be a drag. Add the checklist to your repo, drop Helmet & rate-limiting into your app today, and let CI fail builds that introduce new vulns.
Sources
- OWASP Top 10 2021
- Nodejs Security WG CVE Reports 2023-24
- Snyk State of Open Source Security 2025
✨ Thank you for reading and I hope you find it helpful. I sincerely request for your feedback in the comment’s section.
