Day 46 of #100DayOfCode — Security (Rate limiting CORS Helmet)
Source: Dev.to
What is Rate Limiting?
Why it matters
It protects your API from:
- Brute‑force attacks
- DDoS attempts
- API abuse
Example (Express.js)
import express from "express";
import rateLimit from "express-rate-limit";
const app = express();
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP
message: "Too many requests, please try again later."
});
app.use(limiter);
app.get("/", (req, res) => {
res.send("Hello World!");
});
app.listen(3000);
Use Cases
- Login endpoints (prevent brute force)
- Public APIs (avoid spam)
- Password reset routes
What is CORS?
CORS (Cross‑Origin Resource Sharing) controls which domains can access your backend.
Why it matters
Browsers block requests from unknown origins by default; CORS lets you define who is allowed.
Example (Express.js)
import cors from "cors";
app.use(
cors({
origin: "https://yourfrontend.com",
methods: ["GET", "POST"],
credentials: true
})
);
Use Cases
- Allow frontend (React/Vue) to talk to backend
- Restrict API access to trusted domains
- Enable secure cookie sharing
What is Helmet?
Helmet helps secure your app by setting various HTTP headers.
Why it matters
It protects against:
- XSS (Cross‑Site Scripting)
- Clickjacking
- MIME sniffing
Example (Express.js)
import helmet from "helmet";
app.use(helmet());
Use Cases
- Add security headers automatically
- Prevent common web vulnerabilities
- Harden production APIs
Using Rate Limiting, CORS & Helmet Together
When combined, these tools create a strong security layer.
Combined Use Cases
- Protect login routes from brute‑force + restrict origin + secure headers
- Secure public APIs from abuse and unauthorized access
- Build production‑ready backend for SaaS apps
- Prevent bots while allowing only trusted frontend apps
Real‑World Example: Secure Login API
Goals
- Prevent brute‑force attacks → Rate Limiting
- Allow only your frontend → CORS
- Secure headers → Helmet
Full Example
import express from "express";
import rateLimit from "express-rate-limit";
import cors from "cors";
import helmet from "helmet";
const app = express();
// 1. Helmet (Security Headers)
app.use(helmet());
// 2. CORS (Allow only frontend)
app.use(
cors({
origin: "https://myfrontend.com",
methods: ["POST"],
credentials: true
})
);
// 3. Rate Limiting (Protect login)
const loginLimiter = rateLimit({
windowMs: 10 * 60 * 1000, // 10 minutes
max: 5, // only 5 attempts
message: "Too many login attempts, try again later"
});
app.use(express.json());
// Login Route
app.post("/login", loginLimiter, (req, res) => {
const { username, password } = req.body;
if (username === "admin" && password === "1234") {
return res.send("Login successful");
}
res.status(401).send("Invalid credentials");
});
app.listen(3000, () => console.log("Server running on port 3000"));
What’s happening here?
- Helmet → protects headers automatically
- CORS → only allows requests from
myfrontend.com - Rate Limiting → blocks repeated login attempts
This setup significantly reduces attack surfaces.
Final Thoughts
Rate Limiting → prevents abuse
CORS → controls who can access your API
Helmet → secures HTTP headers
Backend security isn’t about adding a single tool; it’s about layering protections. Together, they form a simple yet powerful security baseline for any modern backend. If you’re building APIs and not using these, you’re leaving doors open that attackers are actively looking for.