Api Security ChecklistSAFE
Overview
An agent skill published by revfactory.
459e1bb8f76eOBSERVED · 2026-10-12What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: api-security-checklist
description: "웹앱 API 보안 체크리스트. OWASP Top 10 기반 취약점 점검, 인증/인가 패턴, 입력 검증, Rate Limiting, CORS, CSRF, SQL Injection 방어를 제공하는 backend-dev 확장 스킬. 'API 보안', 'OWASP', '인증 구현', 'SQL Injection', 'XSS 방어', 'CORS 설정', '보안 체크리스트' 등 백엔드 보안 설계 시 사용한다. 단, 침투 테스트 수행이나 WAF 구성은 이 스킬의 범위가 아니다."
---
# API Security Checklist — 웹앱 API 보안 체크리스트
backend-dev 에이전트가 API 개발 시 활용하는 OWASP 기반 보안 체크리스트, 인증 패턴, 방어 코드 가이드.
## 대상 에이전트
`backend-dev` — 이 스킬의 보안 체크리스트를 API 구현에 직접 적용한다.
## OWASP API Security Top 10 점검
| 순위 | 취약점 | 점검 항목 | 방어 |
|------|--------|----------|------|
| A1 | **BOLA** (객체 수준 인가 결함) | 다른 사용자의 리소스 접근 가능? | 모든 엔드포인트에서 객체 소유권 검증 |
| A2 | **인증 결함** | 약한 비밀번호, 무제한 로그인 시도? | bcrypt 해싱, Rate Limit, MFA |
| A3 | **객체 속성 수준 인가** | 숨겨야 할 필드 노출? | 응답 DTO로 필드 필터링 |
| A4 | **무제한 리소스 소비** | 대량 요청으로 서버 마비? | Rate Limiting, 페이지네이션 강제 |
| A5 | **기능 수준 인가 결함** | 관리자 API를 일반 유저가 호출? | RBAC 미들웨어 |
| A6 | **서버 사이드 요청 위조 (SSRF)** | 외부 URL 입력으로 내부 접근? | URL 화이트리스트, 내부 IP 차단 |
| A7 | **보안 설정 오류** | 디버그 모드 노출, 기본 계정? | 프로덕션 설정 분리, 헤더 점검 |
| A8 | **비즈니스 흐름 결함** | 정상 API를 비정상 순서로 호출? | 상태 머신 검증, 비즈니스 규칙 서버측 |
| A9 | **취약 자산 관리** | 미사용 API, 구버전 노출? | API 인벤토리, 버전 폐기 정책 |
| A10 | **안전하지 않은 API 소비** | 외부 API 응답 무조건 신뢰? | 외부 응답 검증, 타임아웃 설정 |
## 인증 (Authentication) 패턴
### JWT 기반 인증
| 항목 | 권장 설정 |
|------|----------|
| Access Token 만료 | 15~30분 |
| Refresh Token 만료 | 7~14일 |
| 알고리즘 | RS256 (비대칭) 또는 HS256 (대칭) |
| 저장소 | httpOnly + secure + sameSite cookie |
| Payload | 최소 정보만 (userId, role) — PII 금지 |
| 갱신 전략 | Silent Refresh 또는 Rotation |
### 비밀번호 정책
- 최소 8자, 대소문자+숫자+특수문자 권장 (강제보다 강도 표시)
- bcrypt (cost factor 12+) 또는 Argon2id
- 비밀번호 히스토리 (최근 5개 재사용 금지)
- 로그인 실패 5회 시 임시 잠금 (15분) 또는 CAPTCHA
## 인가 (Authorization) 패턴
### RBAC (역할 기반)
```
역할 정의: admin, manager, user, viewer
권한 매핑:
admin → *.* (전체)
manager → resource.create, resource.read, resource.update
user → resource.create (own), resource.read (own)
viewer → resource.read (public)
```
### 미들웨어 체인
```
요청 → [Rate Limit] → [인증: JWT 검증] → [인가: 역할 확인] → [입력 검증] → 핸들러
```
## 입력 검증 체크리스트
| 검증 항목 | 방법 | 도구 |
|----------|------|------|
| **타입 검증** | 스키마 검증 | Zod, Joi, class-validator |
| **길이 제한** | 최소/최대 길이 | 스키마에 min/max |
| **패턴 매칭** | 이메일, URL, 전화번호 | 정규식 + 라이브러리 |
| **범위 검증** | 숫자 범위, 날짜 범위 | min/max 값 |
| **열거형** | 허용된 값 목록 | enum 타입 |
| **SQL Injection** | 파라미터화 쿼리 | ORM (Prisma, TypeORM) |
| **XSS** | HTML 이스케이핑 | DOMPurify (클라이언트), 서버 이스케이프 |
| **Path Traversal** | 경로 정규화 | path.resolve + 화이트리스트 |
| **파일 업로드** | 타입/크기 검증 | MIME 타입 + 매직넘버 검증 |
## HTTP 보안 헤더
| 헤더 | 값 | 목적 |
|------|---|------|
| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains` | HTTPS 강제 |
| `X-Content-Type-Options` | `nosniff` | MIME 스니핑 방지 |
| `X-Frame-Options` | `DENY` 또는 `SAMEORIGIN` | 클릭재킹 방지 |
| `Content-Security-Policy` | `default-src 'self'` | XSS 방지 |
| `X-XSS-Protection` | `0` (CSP로 대체) | 레거시 |
| `Referrer-Policy` | `strict-origin-when-cross-origin` | 리퍼러 정보 제한 |
| `Permissions-Policy` | `camera=(), microphone=()` | 브라우저 기능 제한 |
## CORS 설정 가이드
| 환경 | 설정 |
|------|------|
| 개발 | `origin: 'http://localhost:3000'` |
| 프로덕션 | `origin: ['https://example.com']` — 도메인 명시 |
| 금지 | `origin: '*'` + `credentials: true` — 보안 위험 |
필수 설정:
- `methods`: 필요한 메서드만 허용
- `allowedHeaders`: 필요한 헤더만
- `credentials`: 쿠키 필요 시에만 true
- `maxAge`: 프리플라이트 캐싱 (86400초)
## Rate Limiting 전략
| 대상 | 제한 | 구현 |
|------|------|------|
| 인증 엔드포인트 | 5회/분/IP | IP 기반 |
| API 일반 | 100회/분/사용자 | 토큰 기반 |
| 파일 업로드 | 10회/시간/사용자 | 토큰 기반 |
| 비인증 API | 30회/분/IP | IP 기반 |
### 응답 헤더
```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1609459200
Retry-After: 60 (429 응답 시)
```
## 에러 응답 보안
### 프로덕션 에러 응답 규칙
- 내부 구현 세부사항 절대 노출 금지 (스택 트레이스, SQL 쿼리)
- 일관된 에러 형식 사용
- 열거 공격 방지: 로그인 실패 시 "이메일 또는 비밀번호가 올바르지 않습니다" (어느 것이 틀렸는지 X)
### 에러 응답 형식
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "입력값이 올바르지 않습니다",
"details": [
{"field": "email", "message": "유효한 이메일을 입력하세요"}
]
}
}
```
## 민감 데이터 처리
| 데이터 유형 | 저장 | 전송 | 로깅 |
|-----------|------|------|------|
| 비밀번호 | bcrypt 해시만 | HTTPS only | 절대 금지 |
| API Key | 환경변수 | 헤더 (Authorization) | 마스킹 (앞4자리만) |
| 개인정보 (PII) | 암호화 (AES-256) | HTTPS only | 마스킹 |
| 신용카드 | 토큰화 (PG사 위임) | PG사 SDK | 절대 금지 |
| 세션/토큰 | httpOnly cookie | HTTPS only | 절대 금지 |Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (0)
No findings outside the package's declared scope.
Gates applied: no_behavioural_pass.
459e1bb8f76efull audit observations/trust-audit/skill/revfactory__api-security-checklist.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | 459e1bb8f76e | SAFE | B | 89 | first audit |
Questions
Is Api Security Checklist safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Api Security Checklist access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (459e1bb8f76e), read on 2026-10-12. The repository is watched, and a new audit runs when it changes — this is the first audit.