TechFeedTechFeed
Security

API 보안 체크리스트 2026

한 줄 요약: API 보안은 인증 하나로 끝나지 않는다. OWASP API Top 10 기준으로 체크리스트를 만들고, 항목마다 실제 코드 레벨에서 막혀 있는지 확인해야 한다. OWASP는 2023년 API Security Top 10을 갱신했다. 이전 버전 대비 Broken Object Property Level Authorization(BOPLA)이 추가되고, API 특화 위협이 더 구체화됐다.

by

한 줄 요약: 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


OWASP API Security Top 10 — 2023 버전 핵심 정리 — 보안 아키텍처 다이어그램
API 보안 체크리스트 2026 — 보안 아키텍처 다이어그램 (출처: 공식 문서 및 벤치마크 데이터 기반)

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

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 쿠키 설정 (토큰을 쿠키에 담는 경우)

인증과 인가 — 가장 자주 뚫리는 구간 — 위협 모델 시각화
API 보안 체크리스트 2026 — 위협 모델 시각화 (출처: 공식 문서 및 벤치마크 데이터 기반)

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단 검증.

Rate Limiting — 요청 폭탄을 막는 방어선 — 취약점 분석 플로우차트
API 보안 체크리스트 2026 — 취약점 분석 플로우차트 (출처: 공식 문서 및 벤치마크 데이터 기반)
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)을 모두 적용하는 것이 이상적이다.

자주 묻는 질문

더 깊게 공부하려면 어떤 자료를 보면 좋을까요?

출발점은 OWASP API Security Top 10 2023 원문(owasp.org/API-Security)입니다. 이 글의 10개 항목이 각각 어떤 공격 시나리오에서 나오는지 예시까지 실려 있어, API1 BOLA와 API3 BOPLA의 차이 같은 헷갈리는 부분을 정리하기 좋습니다. 실습으로는 OWASP ZAP을 CI/CD에 붙여 배포마다 자동 DAST 스캔을 돌려 보는 것을 권합니다. 인증 쪽을 더 파려면 JWT 검증과 alg none 우회를 다룬 jwt.io 문서, 그리고 입력 검증을 코드로 강제하는 Zod 공식 문서를 함께 보면 본문 코드 예시를 바로 본인 프로젝트에 옮길 수 있습니다.


API 보안 체크리스트 2026, 한 줄로 정리하면 어떻게 되나요?

API 보안은 인증 하나로 끝나는 게 아니라 OWASP API Top 10을 기준으로 체크리스트를 만들고 항목마다 실제 코드 레벨에서 막혀 있는지 확인해야 한다는 것이 핵심입니다. 특히 리소스마다 소유권을 확인하는 인가(BOLA 방어), JWT의 alg none 거부, 모든 입력에 스키마 검증, 로그인 등 민감 엔드포인트에 별도 Rate Limit, HTTPS·HSTS 강제, 이 다섯 축이 전체 위험의 대부분을 차지합니다. 배포 전 인증·전송·입출력·운영 4개 묶음의 점검 항목을 순서대로 통과시키는 것이 실전 적용법입니다.


실무에서 처음 도입할 때 가장 먼저 확인할 것은 무엇인가요?

가장 먼저 막아야 할 것은 API1, BOLA(Object Level Authorization)입니다. 매년 OWASP 상위를 차지하는 단골이고 한 줄 누락으로 전체 데이터가 새기 때문입니다. GET /api/orders/:id 같은 엔드포인트마다 findById가 아니라 findOne에 userId: req.user.id 소유권 필터가 들어 있는지부터 확인하세요. 그 다음 순서는 JWT 검증 시 algorithms 옵션을 명시해 alg: none을 거부하는지, 모든 요청 파라미터에 Zod 같은 스키마 검증을 걸었는지, 로그인 엔드포인트에 별도 Rate Limit이 있는지입니다. 이 네 가지가 전체 위험의 대부분을 차지합니다.


가장 자주 발생하는 실수나 함정은 무엇인가요?

인증(누구인가)만 걸어 두고 인가(무엇을 할 수 있는가)를 빠뜨리는 것이 압도적으로 많은 실수입니다. 로그인 미들웨어는 통과시키지만 정작 12345번 주문이 그 사용자 것인지 확인하지 않아, 공격자가 ID를 1씩 올리며 남의 데이터를 긁어갑니다. 두 번째 함정은 Rate Limit을 IP 기준으로만 잡는 것입니다. 프록시나 CDN 뒤 클라이언트가 한 IP로 묶여, trust proxy와 X-Forwarded-For 신뢰 범위를 잘못 두면 우회되거나 정상 사용자가 차단됩니다. 마지막은 프로덕션 에러 응답에 스택 트레이스나 DB 내부 ID 같은 민감 필드를 그대로 노출하는 것입니다.


다른 대안과 비교했을 때 어떤 상황에 적합한가요?

이 체크리스트는 모바일 앱·SPA·서드파티 연동처럼 외부에 엔드포인트를 노출하는 모든 백엔드에 적합합니다. 공격 표면이 곧 API이기 때문입니다. 다만 적용 강도는 상황에 따라 조절하세요. B2B API라면 IP·계정 단위에 더해 API 키별 일·월 쿼터까지 거는 것이 맞고, 공개 API나 자동화 남용이 우려되는 비즈니스 플로우(API6)라면 Rate Limit과 봇 탐지를 더 빡빡하게 가져가야 합니다. 반대로 같은 출처에서만 호출되는 내부 전용 BFF라면 BOLA 소유권 검증과 입력 검증을 우선하고 CORS·공개 키 관리 비중은 낮춰도 됩니다. 즉 Postman에서는 보이지 않는 브라우저·자동화 클라이언트가 호출하는 API일수록 이 목록 전체가 필요합니다.


보안APIOWASP인증rate-limiting

함께 보면 좋은 문제 해결

관련 포스트