The Security Bugs Node.js Developers Ship to Production
I reviewed code for a startup last year. The code looked clean. The tests passed.
Then I saw this line:
const query = SELECT * FROM users WHERE email = '${req.body.email}'
This is a SQL injection bug. The startup ran this in production for 8 months. No developer or CTO caught it.
These bugs are invisible because the code works. It works until a user types a malicious command into an input field.
Stop these 5 common mistakes:
- Raw SQL with user input Do not use template literals for queries. This allows attackers to access your database.
- Bad: const query =
SELECT * FROM users WHERE email = '${email}' - Good: Use parameterized queries. const query = 'SELECT * FROM users WHERE email = $1' db.query(query, [email])
Leaking secrets in Git Developers often commit .env files to repositories. This exposes your database URLs and API keys. Always add .env to your .gitignore file.
Using jwt.decode instead of jwt.verify jwt.decode only reads the token. It does not check if the token is real. Anyone can forge a decoded token.
- Bad: const user = jwt.decode(token)
- Good: Always verify the signature. const user = jwt.verify(token, process.env.JWT_SECRET)
- Missing rate limiting on auth endpoints Without rate limiting, attackers can try millions of passwords via brute force. Use a library to limit login attempts.
- Good: Add a limit of 10 attempts per 15 minutes.
- Verbose error messages Sending raw error messages to the client helps attackers map your system. They see your table names and database types.
- Bad: res.status(500).json({ error: error.message })
- Good: Log the error internally. Send a generic message to the user. res.status(500).json({ error: 'Something went wrong' })
Before you ship an endpoint, ask one question: What happens if a user sends unexpected data?
Security bugs are rarely complex. They happen when you forget to think about bad actors.
What security bug have you found in production?
Source: https://dev.to/manolito99/the-security-bug-every-nodejs-developer-ships-to-production-49e6
