TechFeedTechFeed
Security

API 보안 체크리스트 2026

OWASP API Top 10 기반 API 보안 체크리스트. 인증, Rate Limiting, 입력 검증, HTTPS 강제 등 실전 가이드.

한 줄 요약: API 보안은 인증 하나로 끝나지 않는다. OWASP API Top 10 기준으로 체크리스트를 만들고, 항목마다 실제 코드 레벨에서 막혀 있는지 확인해야 한다.

2026년 현재 API는 대부분의 앱에서 가장 넓은 공격 표면이다. 모바일 앱, SPA, 서드파티 연동 — 모두 API를 통해 데이터를 주고받는다. 방어 없이 열어둔 엔드포인트 하나가 전체 데이터베이스를 노출시킨다. 이 글은 OWASP API Security Top 10(2023 버전)을 기준으로, 실무에서 바로 적용할 수 있는 체크리스트와 코드 예시를 제공한다.

OWASP API Security Top 10 — 2023 버전 핵심 정리

OWASP는 2023년 API Security Top 10을 갱신했다. 이전 버전 대비 Broken Object Property Level Authorization(BOPLA)이 추가되고, API 특화 위협이 더 구체화됐다.

순위항목핵심 위험
API1Broken Object Level Authorization다른 사용자 리소스에 접근
API2Broken Authentication인증 우회, 토큰 탈취
API3Broken Object Property Level Authorization과도한 필드 노출 / 쓰기 허용
API4Unrestricted Resource ConsumptionRate Limit 없어 DoS 가능
API5Broken Function Level Authorization관리자 엔드포인트 일반 접근
API6Unrestricted Access to Sensitive Business Flows자동화 공격으로 비즈니스 로직 남용
API7Server Side Request Forgery서버를 프록시로 내부망 접근
API8Security Misconfiguration기본 설정, 에러 노출, CORS 오설정
API9Improper Inventory Management미문서 엔드포인트, 구버전 API
API10Unsafe Consumption of APIs서드파티 API 신뢰 과도

출처: OWASP API Security Top 10 2023

인증과 인가 — 가장 자주 뚫리는 구간

API1(BOLA)와 API2(Broken Authentication)는 매년 상위를 차지하는 단골 취약점이다. 인증은 '누구인가'를 확인하고, 인가는 '무엇을 할 수 있는가'를 제어한다. 두 가지가 모두 올바르게 구현되어야 한다.

BOLA — Object Level Authorization 체크

가장 흔한 패턴: GET /api/orders/12345에서 12345가 현재 로그인 사용자의 주문인지 확인하지 않는 경우. 공격자가 ID를 1씩 바꿔가며 다른 사용자 데이터를 긁어간다.

BOLA 취약 코드 vs 안전한 코드 (Node.js / Express)
// 취약한 코드 — ID만 확인, 소유권 미검사 app.get('/api/orders/:id', authenticate, async (req, res) => { const order = await Order.findById(req.params.id); res.json(order); // 다른 사람 주문도 반환됨 }); // 안전한 코드 — 소유권 필터 추가 app.get('/api/orders/:id', authenticate, async (req, res) => { const order = await Order.findOne({ _id: req.params.id, userId: req.user.id // 반드시 현재 사용자 소유인지 확인 }); if (!order) return res.status(404).json({ error: 'Not found' }); res.json(order); });

인증 체크리스트

  • JWT 서명 알고리즘을 alg: none 허용하지 않는지 확인 — 공격자가 알고리즘을 none으로 바꿔 서명 우회 시도
  • 토큰 만료(exp) 설정 — Access Token 15분~1시간, Refresh Token 7~30일
  • 로그인 실패 횟수 제한 — IP별 또는 계정별 연속 실패 5~10회 후 잠금 또는 CAPTCHA
  • 비밀번호 재설정 토큰의 단일 사용 보장 — 사용 즉시 무효화
  • OAuth2 state 파라미터로 CSRF 방어
  • httpOnly + Secure + SameSite=Strict 쿠키 설정 (토큰을 쿠키에 담는 경우)

Rate Limiting — 요청 폭탄을 막는 방어선

Rate Limiting이 없는 API는 무차별 대입 공격(Brute Force), 크리덴셜 스터핑, DoS 공격에 그대로 노출된다. API4(Unrestricted Resource Consumption)가 이 취약점을 다룬다.

Rate Limiting 전략은 세 가지 레벨에서 동시에 적용해야 효과적이다:

  • IP 레벨: 동일 IP에서 초당/분당 요청 수 제한. 일반 사용자는 보통 분당 60~100회를 넘지 않는다.
  • 계정 레벨: 로그인 시도, 비밀번호 변경, OTP 검증 등 민감 엔드포인트는 계정 단위로 별도 제한.
  • API 키 레벨: B2B API라면 키별로 일/월 쿼터 설정.
Express + express-rate-limit 적용 예시
const rateLimit = require('express-rate-limit'); // 일반 API — 15분에 100회 const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, standardHeaders: true, legacyHeaders: false, message: { error: 'Too many requests, please try again later.' } }); // 로그인 엔드포인트 — 15분에 10회 (더 엄격) const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 10, skipSuccessfulRequests: true // 성공한 요청은 카운트 제외 }); app.use('/api/', apiLimiter); app.post('/api/auth/login', loginLimiter, loginHandler); app.post('/api/auth/otp', loginLimiter, otpHandler);
주의: Rate Limiting을 IP 기반으로만 구현하면 프록시·CDN 뒤에 있는 클라이언트를 제대로 식별하지 못한다. trust proxy 설정을 확인하고, X-Forwarded-For 헤더를 신뢰하는 범위를 명확히 지정해야 한다. 잘못 설정하면 Rate Limit이 우회되거나 정상 사용자가 차단된다.

Input Validation — 들어오는 데이터를 믿지 않는다

API로 들어오는 모든 입력은 악의적이라고 가정하고 검증해야 한다. SQL Injection, NoSQL Injection, XSS, 경로 순회(Path Traversal) 공격의 대부분은 검증 누락에서 시작된다.

검증 레이어

  • 타입 검증: 숫자 파라미터에 문자열 허용 금지. parseInt나 스키마 검증 라이브러리로 강제.
  • 길이 제한: 모든 문자열 필드에 최대 길이 설정. 이메일 254자, 비밀번호 128자 등.
  • 형식 검증: 이메일, URL, UUID 등은 정규식 또는 전용 파서로 검증.
  • 허용 목록(Allowlist) 우선: 차단 목록보다 허용 목록으로 검증. 허용된 값 외 전부 거부.
  • 파일 업로드: MIME 타입 + 확장자 + 파일 시그니처(매직 바이트) 3단 검증.
Zod를 이용한 요청 검증 (TypeScript / Node.js)
import { z } from 'zod'; const CreateOrderSchema = z.object({ productId: z.string().uuid(), quantity: z.number().int().min(1).max(100), shippingAddress: z.object({ street: z.string().max(200), city: z.string().max(100), postalCode: z.string().regex(/^[0-9]{5}$/) }) }); app.post('/api/orders', authenticate, async (req, res) => { const result = CreateOrderSchema.safeParse(req.body); if (!result.success) { return res.status(400).json({ error: 'Validation failed', details: result.error.flatten() }); } const data = result.data; // 타입 안전, 검증 완료된 데이터 // ... 주문 처리 로직 });

HTTPS 강제와 API 키 관리

HTTPS는 선택이 아니라 필수다. HTTP로 전송된 인증 토큰과 API 키는 네트워크 스니핑으로 그대로 노출된다.

HTTPS 강제 체크리스트

  • HTTP 요청을 HTTPS로 301 리디렉션 — 서버 레벨에서 설정
  • HSTS(HTTP Strict Transport Security) 헤더 설정: Strict-Transport-Security: max-age=31536000; includeSubDomains
  • TLS 1.2 이상만 허용 — TLS 1.0, 1.1은 비활성화
  • 인증서 자동 갱신 설정 (Let's Encrypt + Certbot 또는 클라우드 ACM)

API 키 관리 체크리스트

  • API 키를 코드에 하드코딩 금지 — 환경 변수 또는 Secret Manager 사용
  • 키별로 최소 권한만 부여 — 읽기 전용 키는 쓰기 권한 없어야 함
  • 키 로테이션 주기 설정 — 90~180일 권장, 노출 즉시 즉각 교체
  • 키 사용 로그 기록 — 비정상 패턴(새벽 대량 호출, 해외 IP) 알림 설정
  • 키 접두사 패턴 도입 — sk_live_xxx, pk_test_xxx 형태로 환경과 유형 식별 가능하게
HSTS + 보안 헤더 설정 (Express / helmet)
const helmet = require('helmet'); app.use(helmet({ hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }, contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'"] } } })); // HTTP → HTTPS 리디렉션 app.use((req, res, next) => { if (req.headers['x-forwarded-proto'] !== 'https' && process.env.NODE_ENV === 'production') { return res.redirect(301, 'https://' + req.headers.host + req.url); } next(); });
팁: API 키를 git 저장소에 커밋한 적이 있다면 키 교체만으로 끝나지 않는다. git history에 키가 남아있으면 git filter-branch 또는 BFG Repo Cleaner로 히스토리에서 제거해야 한다. GitHub는 노출된 시크릿을 자동으로 탐지해서 경고를 보내지만, 모든 저장소가 GitHub인 것은 아니다.

API 보안 체크리스트 — 배포 전 최종 점검

배포 전 다음 항목을 순서대로 점검한다. 항목별로 '확인됨 / 해당 없음 / 미완료' 중 하나로 표시한다.

인증/인가

  • 모든 보호 엔드포인트에 인증 미들웨어 적용 여부
  • Object Level Authorization — 리소스 소유자 확인 로직 존재 여부
  • 관리자 전용 엔드포인트 역할 기반 접근 제어(RBAC) 적용 여부
  • JWT 알고리즘 명시 및 alg: none 거부 설정

전송 보안

  • HTTPS 전용, HTTP 리디렉션 설정
  • HSTS 헤더 설정
  • TLS 버전 1.2 이상만 허용

입력/출력

  • 모든 요청 파라미터에 스키마 검증 적용
  • 에러 응답에 스택 트레이스 미포함 (프로덕션)
  • 응답에 필요한 필드만 포함 — 민감 필드(password hash, 내부 ID 등) 제외

운영

  • Rate Limiting 적용 — 일반 API + 민감 엔드포인트 별도 설정
  • API 키 및 시크릿 환경 변수 또는 Secret Manager로 관리
  • 요청/응답 로그 수집 — 개인정보 필드는 마스킹 처리
  • 구버전 API 엔드포인트 비활성화 또는 문서 최신화
참고: OWASP는 API 보안 테스트를 위한 자동화 도구도 제공한다. OWASP ZAP을 CI/CD 파이프라인에 통합하면 배포마다 기본 취약점 스캔을 자동화할 수 있다. 정적 분석(SAST)과 동적 분석(DAST)을 모두 적용하는 것이 이상적이다.
보안APIOWASP인증rate-limiting

관련 포스트

인증 구현 가이드 2026 — JWT, OAuth, Passkey2026-02-20JWT vs 세션 인증 — 무엇을 선택할 것인가2026-03-07OWASP Top 10 2026 — 웹 보안 필수 체크리스트2026-02-18CORS 완벽 이해 — 왜 차단되고 어떻게 해결하나2026-03-08