보안 감사 스킬
웹 애플리케이션 코드베이스에 대해 엄격한 정적 보안 감사를 수행합니다. PASS / FAIL / MANUAL-REVIEW 요약 테이블과 파일:라인 증거, 위험 설명, 수정 코드가 포함된 개별 발견 블록을 생성합니다.
1단계 — 스택 분석
코드를 스캔하기 전에 package.json, 설정 파일, README를 읽고 다음 질문에 답하세요:
- 프레임워크: SvelteKit / Next.js / Express / FastAPI 등
- 데이터베이스 드라이버: 매개변수화(LibSQL, pg, Prisma) vs. 원시 문자열(저수준 드라이버)
- 인증 메커니즘: JWT / HMAC 토큰 / 세션 / OAuth
- 배포 대상: Fly.io / Cloudflare / Vercel / bare Node — 속도 제한 및 감사 로그를 위해 신뢰할 IP 헤더가 결정됩니다(
Fly-Client-IPvsCF-Connecting-IPvsX-Forwarded-For). 잘못된 헤더를 신뢰하면 공격자가 출발지 IP를 위조할 수 있습니다. - 파일 업로드: 유/무 — 있는 경우 저장 위치(로컬 파일 시스템, S3 호환, CDN)
- 외부 아웃바운드 호출: 이메일 API, 웹훅, 미디어 가져오기 — 잠재적인 SSRF 표면
2단계를 시작하기 전에 스택 요약을 한 문단으로 작성하세요. 여기서 잘못된 가정은 잘못된 발견으로 이어집니다.
2단계 — 스캔
필수 읽기: references/security-checklist.md
특정 단일 엔드포인트 검토를 위해 references/security-checklist.md를 불러오지 마세요. 그러면 작업 범위를 넘어 확장됩니다. 전체 코드베이스 감사 시에만 불러오세요.
체크리스트의 모든 카테고리를 순서대로 검토하세요. 그룹을 건너뛰려면 보고서에 서면 사유를 기록해야 합니다.
각 카테고리별로:
- 관련 소스 파일을 읽으세요. 기억에 의존하여 PASS로 표시하지 마세요.
- 파일이 없으면 MANUAL-REVIEW로 표시하고 참고 사항을 기록하세요.
- 판정(PASS / FAIL / MANUAL-REVIEW)과 한 줄 증거 메모를 기록하세요.
리포지토리가 너무 커서 모든 파일을 읽을 수 없다면 위험도에 따라 우선순위를 정하세요: 인증 흐름 및 토큰 처리 우선, 그 다음 입력/출력 경계, 그 다음 종속성 설정. 건너뛴 파일을 기록하세요.
3단계 — 분류
원시 스캔 노트를 검토하세요. 각 항목에 판정 규칙을 적용하세요:
- PASS — 관련 코드를 읽고 해당 통제가 마련되어 있음을 확인했습니다. 파일:라인을 인용하세요.
- FAIL — 확인되고 악용 가능한 취약점을 발견했습니다. 코드 스니펫이 있습니다. 수정 코드를 작성할 수 있습니다.
- MANUAL-REVIEW — 판정에 런타임 컨텍스트, 인프라 접근 권한 또는 사람의 판단이 필요합니다(예: "이 토큰이 Turso 대시보드에서 읽기 전용 범위를 가지고 있는지 확인").
판정을 내리기 전에 스스로에게 물어보세요: "지금까지 읽은 내용만으로 바로 수정 코드를 작성할 수 있는가?" 예 → FAIL. 아니오 → MANUAL-REVIEW.
보고서를 부드럽게 하기 위해 FAIL을 MANUAL-REVIEW로 하향 조정하지 마세요.
4단계 — 보고서
먼저 요약 테이블:
| # | 카테고리 | 상태 | 참고 |
|---|---|---|---|
| 1 | SQL 인젝션 | PASS | 전체적으로 매개변수화됨 |
| 2 | XSS | FAIL | 사용자 제어 필드에 {@html} 사용 — 발견 항목 참조 |
| … | … | … | … |
그런 다음, 모든 FAIL 및 MANUAL-REVIEW에 대해 발견 블록:
### [N]. 카테고리 — FAIL
**파일:** `src/lib/example.ts:42`
**스니펫:**
cookies.set(name, token, { httpOnly: true }) // ← Secure 플래그 누락
**위험:** 비프로덕션 환경에서 일반 HTTP를 통해 쿠키 전송; 수동적 MITM에 의해 캡처됨.
**수정:**
cookies.set(name, token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
});
MANUAL-REVIEW 블록은 동일한 형식을 사용하지만 수정 대신 조치를 사용하여 사람이 확인해야 할 내용과 위치를 설명합니다.
PASS 항목은 요약 테이블에만 나타나며 블록은 없습니다.
절대 하지 말아야 할 것
-
파일을 읽지 않고 PASS로 표시하지 마세요 대신: 파일을 읽고 증거 메모에 파일:라인을 인용하세요. 이유: 기억에 기반한 PASS 판정은 잘못된 확신을 만듭니다. 감사의 핵심은 증거입니다.
-
코드 스니펫 없이 FAIL로 표시하지 마세요 대신: 정확히 취약한 라인(들)을 인용하세요. 스니펫을 찾을 수 없으면 MANUAL-REVIEW입니다. 이유: 증거 없는 FAIL은 잡음일 뿐입니다. 개발자는 수정을 위해 정확한 위치가 필요합니다.
-
FAIL과 MANUAL-REVIEW를 혼동하지 마세요 대신: FAIL = 지금 바로 수정 코드를 작성할 수 있음. MANUAL-REVIEW = 작성할 수 없으며, 그 이유를 설명합니다. 이유: 둘을 혼합하면 보고서의 실행 가능성이 파괴됩니다.
-
1단계 스택 분석을 절대 건너뛰지 마세요 대신: 무엇이든 스캔하기 전에
package.json과 설정 파일 하나를 읽으세요. 이유: 신뢰할 IP 헤더, 유효한 CSP 접근 방식, 적용할 인증 모델은 모두 스택에 따라 달라집니다. 잘못된 가정은 잘못된 판정으로 이어집니다. -
프로젝트의 프레임워크/라이브러리와 일치하지 않는 수정 코드를 보고하지 마세요 대신: 이미 사용 중인 정확한 API를 사용하여 수정 코드를 작성하세요(예:
res.setHeader가 아닌 SvelteKitcookies.set). 이유: 컴파일되지 않는 일반적인 수정 코드는 무시됩니다. 프레임워크별 수정 코드는 병합됩니다. -
소스 파일을 읽지 않은 카테고리에 대한 발견 블록을 작성하지 마세요 대신: 파일을 열고 읽은 후 블록을 작성하세요. 이유: 파일 증거 없는 발견 블록은 주장일 뿐 감사가 아닙니다. 잘못된 것으로 판명되면 전체 보고서에 대한 신뢰를 무너뜨립니다.
-
큰 리포지토리에서 파일을 조용히 건너뛰지 마세요 대신: 위험도에 따라 우선순위를 정하고(인증/토큰 처리 → 입출력 경계 → 종속성 설정) 건너뛴 모든 파일을 보고서에 명시적으로 나열하세요. 이유: 조용한 건너뛰기는 감사의 범위 주장을 검증 불가능하게 만듭니다. 불완전한 스캔에 대한 깨끗한 보고서는 잘못된 전면 경보 해제로 읽힙니다.