Building APIs with Express.js is fast and enjoyable, but security is often treated as something to handle later. Unfortunately, small security mistakes can expose applications to attacks, data leaks, and service disruptions.
In this article, we'll look at 10 common security mistakes developers make when building Express APIs and how to fix them.
1. Not Using Security Headers
By default, Express does not add many security-related HTTP headers.
Without proper headers, applications may be vulnerable to attacks such as clickjacking and MIME-type sniffing.
Fix
Install Helmet:
npm install helmet
Use it in your application:
import helmet from "helmet";
app.use(helmet());
2. No Rate Limiting
Without rate limiting, attackers can spam endpoints, brute-force login forms, or overwhelm your server.
Fix
npm install express-rate-limit
import rateLimit from "express-rate-limit";
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
});
app.use(limiter);
3. Exposing Stack Traces in Production
Detailed error messages may reveal sensitive implementation details.
Bad Example
res.status(500).json({
error: err.stack,
});
Better
res.status(500).json({
error: "Internal Server Error",
});
Keep detailed logs on the server, not in client responses.
4. Trusting User Input
Never trust incoming data.
Attackers can send malformed requests, inject malicious payloads, or bypass assumptions.
Fix
Validate all incoming requests using libraries such as:
- Zod
- Joi
- express-validator
Example:
const schema = z.object({
email: z.string().email(),
});
5. Hardcoding Secrets
One of the most common mistakes is storing secrets directly in source code.
Avoid
const API_KEY = "my-secret-key";
Better
const API_KEY = process.env.API_KEY;
Store secrets in environment variables instead.
6. Missing Request Size Limits
Attackers can send extremely large payloads and consume server resources.
Fix
app.use(express.json({
limit: "1mb",
}));
Choose limits appropriate for your application.
7. Using Outdated Dependencies
Security vulnerabilities are regularly discovered in npm packages.
Fix
Run:
npm audit
And keep dependencies updated:
npm update
8. Weak Authentication Practices
Common mistakes include:
- Weak passwords
- Long-lived tokens
- Missing password hashing
- No multi-factor authentication
Fix
Use:
- bcrypt or Argon2 for password hashing
- JWT expiration times
- MFA where appropriate
9. No Logging or Monitoring
If an incident occurs, logs are often the only way to understand what happened.
Fix
Implement structured logging:
import morgan from "morgan";
app.use(morgan("combined"));
Monitor unusual traffic patterns and failed authentication attempts.
10. Assuming HTTPS Is Optional
HTTP traffic can be intercepted and modified.
Fix
Always use HTTPS in production.
If you're deploying behind a reverse proxy:
app.set("trust proxy", 1);
And enforce HTTPS wherever possible.
Final Thoughts
Security isn't a feature you add at the end of a project. It should be part of the development process from day one.
The good news is that most of these issues can be fixed with just a few lines of code.
While exploring common Express security challenges, I've also been building FortressJS, an open-source project focused on making API security easier for Node.js developers.
What security mistake do you see most often in Express applications?
Thanks for reading! 🚀
Top comments (0)