#100DayOfCode 46일차 — 보안 (Rate limiting CORS Helmet)
Source: Dev.to
Rate Limiting이란?
왜 중요한가
API를 다음으로부터 보호합니다:
- 무차별 대입 공격
- DDoS 시도
- API 남용
예시 (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);
사용 사례
- 로그인 엔드포인트 (무차별 대입 방지)
- 공개 API (스팸 방지)
- 비밀번호 재설정 라우트
CORS란?
CORS(Cross‑Origin Resource Sharing)는 어떤 도메인이 백엔드에 접근할 수 있는지를 제어합니다.
왜 중요한가
브라우저는 기본적으로 알 수 없는 출처의 요청을 차단합니다; CORS를 통해 누가 허용되는지 정의할 수 있습니다.
예시 (Express.js)
import cors from "cors";
app.use(
cors({
origin: "https://yourfrontend.com",
methods: ["GET", "POST"],
credentials: true
})
);
사용 사례
- 프론트엔드(React/Vue)가 백엔드와 통신하도록 허용
- 신뢰할 수 있는 도메인에만 API 접근 제한
- 안전한 쿠키 공유 활성화
Helmet이란?
Helmet은 다양한 HTTP 헤더를 설정하여 앱을 보호합니다.
왜 중요한가
다음으로부터 보호합니다:
- XSS(Cross‑Site Scripting)
- 클릭재킹
- MIME sniffing
예시 (Express.js)
import helmet from "helmet";
app.use(helmet());
사용 사례
- 보안 헤더를 자동으로 추가
- 일반적인 웹 취약점 방지
- 프로덕션 API 강화
Rate Limiting, CORS & Helmet을 함께 사용하기
이 도구들을 결합하면 강력한 보안 레이어를 만들 수 있습니다.
결합 사용 사례
- 로그인 라우트를 무차별 대입으로부터 보호 + 출처 제한 + 보안 헤더
- 공개 API를 남용 및 무단 접근으로부터 보호
- SaaS 앱을 위한 프로덕션 준비 백엔드 구축
- 봇을 차단하고 신뢰할 수 있는 프론트엔드 앱만 허용
실제 예시: 보안 로그인 API
목표
- 무차별 대입 공격 방지 → Rate Limiting
- 프론트엔드만 허용 → CORS
- 보안 헤더 적용 → Helmet
전체 예시
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"));
여기서 무슨 일이 일어나고 있나요?
- Helmet → 헤더를 자동으로 보호
- CORS →
myfrontend.com에서 온 요청만 허용 - Rate Limiting → 반복적인 로그인 시도를 차단
이 설정은 공격 표면을 크게 줄여줍니다.
마무리 생각
Rate Limiting → 남용 방지
CORS → API에 접근할 수 있는 주체 제어
Helmet → HTTP 헤더 보안
백엔드 보안은 단일 도구를 추가하는 것이 아니라 보호를 층층이 쌓는 것입니다. 이 세 가지를 함께 사용하면 현대 백엔드에 필요한 간단하면서도 강력한 보안 기준을 만들 수 있습니다. API를 구축하면서 이 도구들을 사용하지 않는다면, 공격자가 적극적으로 찾는 문을 열어두는 셈입니다.