Securing Your Express App: Best Practices & Essential Middleware

When setting up an Express.js application, security should be a top priority. Web apps are vulnerable to various attacks like DDoS, XSS, SQL Injection, and CSRF, so implementing the right security measures can prevent exploits and protect user data.

In this blog, we’ll explore six essential security middleware to secure your Express app. 🚀


1️⃣ Rate Limiting with express-rate-limit (Prevent DDoS & Brute-Force)

By limiting the number of requests from a single IP, we can prevent DDoS attacks and brute-force login attempts.

🔹 Installation & Usage

const rateLimit = require("express-rate-limit");

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per window
  message: "Too many requests, please try again later.",
});

app.use(limiter);

📌 Why? Prevents abuse by blocking excessive requests from the same user.


2️⃣ Secure Headers with helmet (Prevent Common Web Attacks)

helmet helps set HTTP headers properly to prevent common vulnerabilities like clickjacking, sniffing, and framing attacks.

🔹 Installation & Usage

const helmet = require("helmet");
app.use(helmet());

📌 Why? Protects your app from security misconfigurations and improves browser security.


3️⃣ Input Validation with Zod (Prevent Injection Attacks)

Validating user input is crucial to avoid XSS, SQL Injection, and NoSQL Injection.

🔹 Installation & Usage

const { z } = require("zod");

const userSchema = z.object({
  username: z.string().min(3).max(20),
  email: z.string().email(),
  age: z.number().positive(),
});

const validateUser = (req, res, next) => {
  const result = userSchema.safeParse(req.body);
  if (!result.success) return res.status(400).json(result.error);
  next();
};

app.post("/register", validateUser, (req, res) => {
  res.json({ message: "Valid data!" });
});

📌 Why? Ensures that only clean and structured data enters your system.


4️⃣ Prevent Parameter Pollution with hpp (Avoid Malicious Query Overwrites)

Attackers can inject duplicate query parameters to bypass security mechanisms. hpp helps sanitize such input.

🔹 Installation & Usage

const hpp = require("hpp");
app.use(hpp());

📌 Why? Prevents attackers from sending malformed requests to manipulate application behavior.


5️⃣ XSS Protection with xss-clean (Prevent Cross-Site Scripting)

User input can contain malicious scripts that execute in a victim’s browser. xss-clean removes such payloads.

🔹 Installation & Usage

const xss = require("xss-clean");
app.use(xss());

📌 Why? Prevents XSS attacks where attackers inject malicious JavaScript into web pages.


6️⃣ Secure API Access with cors (Control Cross-Origin Requests)

CORS (Cross-Origin Resource Sharing) prevents unauthorized access to your API from other origins.

🔹 Installation & Usage

const cors = require("cors");
app.use(cors({ origin: "https://yourfrontend.com" }));

📌 Why? Protects your API from unauthorized access by restricting which domains can interact with it.


🔒 Final Security Checklist

  • Enable rate limiting to prevent DDoS.

  • Use Helmet for secure headers.

  • Validate input with Zod to prevent injection attacks.

  • Protect against parameter pollution with HPP.

  • Prevent XSS attacks with xss-clean.

  • Configure CORS to secure API access.

Conclusion

Security is not an option; it’s a necessity! By using the right middleware and best practices, you can protect your Express app from common attacks and ensure a safer experience for users.

0
Subscribe to my newsletter

Read articles from Md Sohail Ansari directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Md Sohail Ansari
Md Sohail Ansari

Final Year Undergrad at IIIT Bhagalpur and a Full Stack Web Developer. Portfolio: https://www.heysohail.me/