Introduction
Security is a crucial aspect of any application. In this chapter, we will explore best practices for securing Node.js applications against common vulnerabilities such as injection attacks, authentication flaws, and misconfigurations.
1. Using Environment Variables for Sensitive Data
- Never store sensitive information (API keys, database credentials) directly in the code.
- Use dotenv to manage environment variables.
Install dotenv:
npm install dotenv
Example:
require("dotenv").config();
const dbPassword = process.env.DB_PASSWORD;
2. Securing Express Applications
Helmet Middleware for Security Headers
npm install helmet
const helmet = require("helmet");
app.use(helmet());
Preventing Cross-Site Scripting (XSS)
npm install xss-clean
const xss = require("xss-clean");
app.use(xss());
Rate Limiting to Prevent Bruteforce Attacks
npm install express-rate-limit
const rateLimit = require("express-rate-limit");
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
});
app.use(limiter);
3. Protecting Against SQL Injection and NoSQL Injection
Use Parameterized Queries (SQL)
const db = require("mysql2");
db.execute("SELECT * FROM users WHERE id = ?", [userId]);
Validate Inputs to Prevent NoSQL Injection
npm install express-validator
const { body } = require("express-validator");
app.post("/user", [body("email").isEmail()], (req, res) => {
res.send("Valid email");
});
4. Authentication and Authorization Best Practices
Secure Password Hashing with bcrypt
npm install bcrypt
const bcrypt = require("bcrypt");
const hashedPassword = await bcrypt.hash("password123", 10);
JSON Web Tokens (JWT) for Authentication
npm install jsonwebtoken
const jwt = require("jsonwebtoken");
const token = jwt.sign({ userId: 123 }, process.env.JWT_SECRET, { expiresIn: "1h" });
5. Enforcing HTTPS and Secure Cookies
Redirect HTTP to HTTPS
app.use((req, res, next) => {
if (req.headers["x-forwarded-proto"] !== "https") {
return res.redirect("https://" + req.headers.host + req.url);
}
next();
});
Secure Cookies
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { secure: true, httpOnly: true }
}));
Exercises
- Set up environment variables for database credentials.
- Implement rate-limiting and Helmet in an Express app.
- Secure an API endpoint using JWT authentication.
- Validate user input to prevent SQL and NoSQL injection attacks.
- Enforce HTTPS and secure session cookies.
Conclusion
This chapter covered security best practices in Node.js, including data protection, authentication, input validation, and HTTPS enforcement. In the next chapter, we will explore real-time applications with WebSockets.