1단계
위협 모델 · OWASP 요약
20 분
위협 모델 · OWASP 요약
"보안은 어디서부터 어디까지?" 에 정답은 없지만 실제 공격 분포 를 알면 우선순위가 생깁니다.
1. OWASP Top 10 (2021 기준, 2024 개정 유사)
- Broken Access Control
- Cryptographic Failures
- Injection (SQL · NoSQL · command)
- Insecure Design
- Security Misconfiguration
- Vulnerable and Outdated Components
- Identification and Authentication Failures
- Software and Data Integrity Failures
- Security Logging and Monitoring Failures
- Server-Side Request Forgery (SSRF)
출처: owasp.org/Top10.
2. 실제 사고 대부분 Top 3
- 접근 제어 실수 — "URL 바꾸니 다른 사용자 데이터 보임"
- 인증 실패 — 약한 패스워드 · 세션 탈취 · MFA 미적용
- Injection —
WHERE id = ${id}같은 문자열 연결
나머지 7 개는 빈도가 비교적 낮거나 프레임워크가 기본 방어.
3. 위협 모델링 — STRIDE
6 범주로 분류:
- Spoofing — 사칭
- Tampering — 변조
- Repudiation — 부인 (감사 로그 부재)
- Information disclosure — 정보 유출
- Denial of service — 서비스 거부
- Elevation of privilege — 권한 상승
페이지 · API 하나마다 이 6 개를 훑으면 누락된 방어가 보입니다.
4. 경계의 원칙 — "Never trust the client"
클라이언트 입력은 모두 검증 · 인증이 끝난 뒤에도 사용자마다 권한 재확인.
// ❌ 위험
const userId = req.body.userId;
await db.query("DELETE FROM posts WHERE user_id = $1", [userId]);
// ✅ 안전
const sessionUser = await verifySession(req);
await db.query("DELETE FROM posts WHERE user_id = $1", [sessionUser.id]);
URL · body · header 를 신뢰하지 말고 세션에서 user_id.
5. 최소 권한 (Least Privilege)
- 앱 DB 사용자는 필요한 테이블만 access
- 크론 스크립트 전용 DB 사용자 분리
- 프로덕션 접근 IAM 최소화
개발자 편의와 충돌하지만 사고 시 피해 범위를 크게 줄입니다.
6. 방어 깊이 (Defense in Depth)
한 층이 뚫려도 다음 층이 받습니다.
[Caddy / CDN] → [rate limit] → [WAF] → [인증] → [권한] → [입력 검증]
↓
[DB 제약]
각 층이 독립적 오류. SQL injection 을 1 차 · 2 차 · 3 차 (parameterize + input 검증 + DB 제약) 세 번 막음.
7. 보안 ≠ 은폐
security through obscurity 는 오래 못 감. API 구조 · 인증 플로우는 공개되어도 안전한 설계가 목표.
8. 첫 주 내 점검 5 가지
- 모든 mutation API 에 세션 검증
- SQL 파라미터화 (
$1,?) 100% - 비밀번호는 bcrypt · argon2 (절대 평문 · MD5 · SHA1 아님)
- HTTPS 강제 (Caddy 자동)
- 의존성
pnpm audit/npm audit월 1 회
이 5 가지만 잡아도 공격면이 90% 줄어듭니다.
하고픈 말
보안은 한 번에 끝내는 프로젝트가 아니라 지속적 점검. Top 10 · 자주 쓰는 패턴 · 방어 깊이 세 가지 관점을 유지하면 감이 옵니다.
Next
- 02-jwt-refresh-rotation