ch015-pentest · git:20260611.c515831 · 2026-06-11 · sha256 f276618ed72ff80a

ch015-pentest git:20260611.c515831A

Immutable. This exact content is served forever at /api/v1/blob/f276618ed72ff80a.

---
name: ch015-pentest
description: "Run CH015 penetration testing workflows for attacker-minded source-code review, exploit scenarios, POC generation, dry-run or live verification, and security findings."
---

# 모의해킹 (Penetration Testing) Skill

> 대상 프로젝트의 소스코드를 공격자 관점에서 분석하여
> 시나리오 기반 취약점 탐색, POC 생성, 선택적 라이브 검증을 수행합니다.

---

## 서비스 개요

| 항목 | 내용 |
|------|------|
| 서비스명 | 모의해킹 (Pentest) |
| 방법론 | 시나리오 기반 공격 + 방법론 기반 분석 |
| 출력물 | 취약점 상세 + 6-step 영향도 분석 + POC 코드 + 라이브 검증 결과 |
| 코드 수정 | ❌ 없음 (읽기 전용) |

---

## 설계 원칙: 방법론 기반 + 공격자 사고

### 분석 원칙: 방법론, 패턴이 아님

```yaml
Principles:
  No_Pattern_Lists: |
    "특정 프레임워크 구문, grep 패턴, 시크릿 접두사 목록에 의존하지 않는다.
     이런 목록은 닫힌 집합이며, 목록에 없는 위험을 구조적으로 놓친다."

  Use_Methodology: |
    "행위(무엇이 일어나는가)를 질문하고, AI가 감지된 기술 스택에 맞는
     구체적 코드 패턴을 자율적으로 판단하여 탐색한다."

  Attacker_Mindset: |
    "방어자가 아닌 공격자 관점으로 코드를 읽는다.
     '이 기능이 안전한가'가 아니라 '이 기능을 어떻게 악용할 수 있는가'를 질문한다."

  Representative_Examples: |
    "안티패턴/올바른 패턴은 '대표적 예시'로만 제시.
     분석은 이 예시에 한정되지 않으며 — 동일한 구조적 이슈를 가진
     모든 변형이 탐지되어야 한다."
```

---

## Phase 구조

```
Phase 0: Recon          → 공통 정찰 (common/recon.md 참조)
Phase 0.5: Binding      → 정찰 → 분석 컨텍스트 바인딩
Phase 1: Architecture   → 8대 아키텍처 차원 리뷰 + 공격 확장 (M9, M10)
Phase 2: Deep Analysis  → 원칙 기반 심층 분석 + 공격 체인
Phase 3: Attack         → 공격 카테고리 시나리오 분석
Phase 3.5: Creative     → 체크리스트 외 프로젝트 고유 공격 추론
Phase 3.8: Routing Plan → Pentest Routing Plan (시나리오 → Route A~F 배정)
Phase 4: POC            → 검증 가능한 POC 코드 생성
Phase 4.5: Self-Verify  → 분석 결과 자체 검증 (도달 가능성, 보상 제어, 전제조건 분석, 로컬 PoC)
Phase 6.0: Sweep        → 엔드포인트 전수 기본 테스트 (--url 옵션 시, Finding 무관)
Phase 6: Live           → Finding 기반 라이브 검증 (--url 옵션 시)
Phase 5: Report         → 종합 보고서 + 6-step 영향도 분석 + 전제조건 포괄 그룹
Phase 5R: Regulatory    → 규제 영향 참조 (Finding 기반, 해당 시에만)
```

> 실행 순서 주의: Phase 5(Report)는 번호와 달리 **최종 단계**다 — `--url` 옵션 시
> Phase 6.0/6 라이브 검증 결과를 반영한 후 pentest-report.template.md 기반으로
> 보고서를 생성하고, Phase 5R(규제 영향 참조)을 말미에 첨부한다.
> Phase 5는 별도 본문 섹션 없이 위 산출 규칙과 템플릿으로 수행한다.

> **Report Gate 주의 (hooks/report-gate-hook.js)**: engagement_dir 내부에
> 파일명에 `report`/`result`/`summary`/`backlog`가 포함된 `.md`를 Write/Edit하는 순간
> (예: `06_pentest_result.md`) report-gate가 발동하여 raw ledger/convergence
> classification의 분류 완결성을 검증한다. 차단(exit 2)되면 파일명 변경이나
> Bash 리다이렉트로 우회하지 말 것 — 누락 산출물의 보완 주체는 raw ledger는
> VA Phase 4.7, classification은 OffSec Lead Convergence이므로, blocker 사유를
> 반환 메시지로 Lead에 보고하고 보완 후 재시도한다.

---

## Phase 1: 아키텍처 차원 리뷰 + 공격 확장

### 모듈 로딩

Pentest Phase 1은 VA의 A1-A8 아키텍처 차원 분석을 기반으로 합니다. 다음 모듈을 로드합니다:

```yaml
Required_Modules:
  VA_Dimensions: "offsec/va/SKILL.md → Phase 1~3 (A1-A8 아키텍처 차원 정의)"
  Compliance: "offsec/va/compliance.md → OWASP/Secure Coding/NIST 매핑 기준"
  Compensating_Control: "common/compensating-control.md → 보상 제어 4단계 검증"
  Deep_Analysis: "offsec/va/deep-analysis.md → 원칙 기반 심층 분석"
```

VA의 A1-A8 아키텍처 차원 리뷰를 수행하되, **공격자 관점**에서 다음을 추가로 추적합니다:

- **강도**: 각 보안 메커니즘의 강도 (강/중/약)
- **우회 가능성**: 공격자가 메커니즘을 우회할 수 있는 경로

### 공격 확장 차원

VA의 A1-A8에 더해 **M9 비즈니스 플로우 무결성**과 **M10 정보 노출 통제**를 추가로 추적합니다.

### M9. 비즈니스 플로우 무결성 (Business Flow Integrity)

소스코드에서 비즈니스 플로우를 추적하여 **설계 수준의 논리적 결함**을 식별합니다.

```yaml
Review_Perspectives:

  Multi_Step_Flow:
    question: "비즈니스 플로우의 단계를 스킵할 수 있는가?"
    methodology: |
      1. 비즈니스 플로우 식별: 생성→실행→정산, 신청→결제→확정
      2. 각 단계별 독립 API 엔드포인트 식별
      3. 중간 단계 스킵 가능성 분석
      4. 단계 간 상태 검증 존재 여부

  Entity_Lifecycle_Abuse:
    question: "비활성/만료된 엔티티로 핵심 기능을 수행할 수 있는가?"
    methodology: |
      1. 소프트 삭제 엔티티로 핵심 기능 수행 가능 여부
      2. 만료된 API 키, 세션, 초대링크로 작업 수행 가능 여부
      3. 각 API에서 is_active/status 검증 일관성

  Competition_Logic:
    question: "경쟁/매칭 로직에 결함이 있는가?"
    methodology: |
      1. 자기 리소스끼리 대결/경쟁 가능 여부
      2. 타인 리소스를 지정하여 이벤트 참가 가능 여부
      3. 상태/진행/점수 직접 변경 가능 여부
      4. 유료 리소스에 무료 엔드포인트로 접근 가능 여부

  Admin_Access_Control:
    question: "관리자 기능에 대한 접근 제어가 일관적인가?"
    methodology: |
      1. URL 직접 접근으로 관리자 페이지 로드 가능 여부
      2. 관리자 API에 네트워크 레벨 보호 존재 여부
      3. 관리자 미들웨어의 일관적 적용

Representative_Anti_Patterns:
  - "비즈니스 플로우 중간 단계 스킵으로 결제 없이 서비스 사용"
  - "소프트 삭제 엔티티가 여전히 핵심 기능에서 유효"
  - "자기 리소스끼리 매칭하여 보상 획득"

Representative_Healthy_Patterns:
  - "각 단계에서 이전 단계 완료 상태 서버 측 검증"
  - "모든 API에서 엔티티 활성 상태 일관되게 체크"
  - "관리자 기능 서버 미들웨어 + 네트워크 레벨 이중 보호"
```

### M10. 정보 노출 통제 (Information Disclosure Control)

```yaml
Review_Perspectives:

  API_Response_Data:
    question: "API 응답에 불필요한 데이터가 포함되는가?"
    methodology: |
      1. SELECT * 또는 과도한 컬럼 조회 패턴
      2. 관계 JOIN 시 불필요 필드 노출
      3. 리더보드/참가자 목록에서 불필요 사용자 정보

  Business_Sensitive:
    question: "비즈니스 민감 정보가 외부에 노출되는가?"
    methodology: |
      1. 리소스 내부 설정(system_prompt, config) 타인에게 노출
      2. 보상 배분/알고리즘/수수료 정보 노출
      3. 서버 버전, 프레임워크 정보 헤더 노출

  PII_Exposure:
    question: "개인식별정보가 불필요하게 노출되는가?"
    methodology: |
      1. 공개 API에 이메일, 전화번호, 실명 포함 여부
      2. JWT 토큰 payload에 PII 포함
      3. 에러 응답에 사용자 식별 정보 포함

Representative_Anti_Patterns:
  - "API 응답에 DB 전체 레코드 반환"
  - "시스템 프롬프트/알고리즘 파라미터가 API로 노출"
  - "공개 리더보드에 이메일/실명 포함"

Representative_Healthy_Patterns:
  - "DTO/시리얼라이저로 응답 필드 명시적 제한"
  - "비즈니스 민감 정보는 서버 측에서만 접근"
  - "PII는 마스킹/해싱 후 노출"
```

### 메커니즘 식별 결과 출력

```
┌──────────────────────────────────────────────────────────────────────┐
│ SECURITY MECHANISM TRACKING                                         │
├──────┬──────────────┬──────────────┬──────────┬─────────────────────┤
│ 코드 │ 차원/메커니즘  │ 위치          │ 강도     │ 우회 가능성          │
├──────┼──────────────┼──────────────┼──────────┼─────────────────────┤
│ A1   │ 인증 아키텍처  │ file:line    │ 강/중/약  │ 없음 / 가능 / 확인됨 │
│ A2   │ 인가 아키텍처  │ file:line    │ 강/중/약  │ 없음 / 가능 / 확인됨 │
│ ...  │ ...          │ ...          │ ...      │ ...                 │
│ M9   │ 비즈니스 플로우 │ file:line    │ 강/중/약  │ 없음 / 가능 / 확인됨 │
│ M10  │ 정보 노출 통제 │ file:line    │ 강/중/약  │ 없음 / 가능 / 확인됨 │
└──────┴──────────────┴──────────────┴──────────┴─────────────────────┘
```

---

## Phase 2: 원칙 기반 심층 분석 + 공격 체인

Phase 1의 아키텍처 차원 리뷰에서 발견된 약점을 기반으로,
보안 원칙에 따른 **자유 추론**과 **공격 체인 분석**을 수행합니다.

```yaml
Security_Principles:
  Least_Privilege: "모든 주체에 필요한 최소 권한만 부여"
  Defense_in_Depth: "단일 보안 레이어가 아닌 다층 방어 구조"
  CIA_Triad: "기밀성, 무결성, 가용성"
  Secure_Defaults: "기본 설정이 안전한 상태"
  Trust_Boundary_Verification: "모든 신뢰 경계에서 데이터 검증"

Attack_Chain_Analysis:
  1_공유_엔티티_매핑: "동일 DB 테이블을 참조하는 모든 엔드포인트 그룹화"
  2_상태_전이_체인: "엔드포인트 A로 상태 변경 → B가 의도치 않은 동작"
  3_권한_에스컬레이션_체인: "일반 기능 조합으로 상위 권한 접근"
  4_콘텐츠_오염_체인: "UGC가 집계/변환을 거쳐 공식 채널에 표시"
  5_자원_고갈_체인: "Rate limit 분산/우회로 시스템 자원 소진"
  6_테넌트_격리_체인: "테넌트 A의 컨텍스트에서 테넌트 B의 데이터 접근/변경"
  7_프롬프트_인젝션_체인: "사용자 입력/UGC → RAG/DB → LLM 프롬프트 → 도구 호출 → 시스템 변경"

Free_Exploration_Areas:
  Business_Logic: "비즈니스 도메인 고유 위협 추론"
  Cryptography: "암호화 코드의 목적 적합성 판단"
  Timing_Races: "동시 요청으로 인한 무결성 위반"
  Cache_Security: "인증 필요 페이지의 CDN 캐싱, 민감 API 캐싱"
  AI_Integration: |
    AI/LLM 통합 코드를 식별하고 공격 시나리오를 구성:
    1. 프롬프트 인젝션 체인: 입력 → 프롬프트 → LLM → 출력 → 시스템 변경
    2. 데이터 유출: 민감 데이터 → 프롬프트 → 외부 API
    3. 에이전시 남용: LLM → 도구 호출 → 무제한 시스템 변경
    4. RAG 포이즈닝: 악의적 콘텐츠 → 벡터 스토어 → 프롬프트 오염
  Multi_Tenancy: |
    멀티테넌트 격리 우회 공격 시나리오:
    1. 테넌트 필터 누락 쿼리를 통한 교차 데이터 접근
    2. 캐시 키 조작으로 다른 테넌트 캐시 데이터 접근
    3. 백그라운드 잡에서 테넌트 컨텍스트 누락으로 데이터 혼재
```

---

## Phase 3: 공격 카테고리 분석

### Category 1: 권한 우회 (Authorization Bypass)

```yaml
점검_항목:
  AUTH-001: "인증 미들웨어 미적용 엔드포인트 — CRITICAL"
  AUTH-002: "JWT 서명 미검증/약한 알고리즘 — CRITICAL"
  AUTH-003: "일반 사용자가 관리자 기능 접근 — CRITICAL"
  AUTH-004: "타인 리소스 접근(IDOR) — HIGH"
  AUTH-005: "서비스키 클라이언트 노출/하드코딩 — CRITICAL"
  AUTH-006: "세션 만료/갱신/무효화 결함 — HIGH"
  AUTH-007: "인가 로직 클라이언트 측 only — HIGH"
  AUTH-008: "BaaS/DB 직접 접근으로 API 인가 우회 — CRITICAL"
  AUTH-009: "특권 함수(SECURITY DEFINER 등) 일반 사용자 노출 — CRITICAL"
```

### Category 2: 메시지 변조 (Message Tampering)

```yaml
점검_항목:
  TAMP-001: "요청 무결성 미검증 (서명/HMAC 없음) — HIGH"
  TAMP-002: "WebSocket 메시지 인증/검증 없음 — MEDIUM"
  TAMP-003: "외부 API 응답 검증 없이 신뢰 — HIGH"
  TAMP-004: "HTTP(비 TLS) 통신으로 MITM 가능 — HIGH"
  TAMP-005: "사용자 입력 HTTP 헤더 삽입(CRLF) — MEDIUM"
```

### Category 3: 데이터 조작 (Data Manipulation)

```yaml
점검_항목:
  DATA-001: "SQL 인젝션 — CRITICAL"
  DATA-002: "레이스 컨디션(TOCTOU) — HIGH"
  DATA-003: "Mass Assignment — HIGH"
  DATA-004: "비즈니스 로직 우회(결제/할인/제한) — HIGH"
  DATA-005: "안전하지 않은 역직렬화 — CRITICAL"
  DATA-006: "파일 업로드 검증 미비 — HIGH"
  DATA-007: "상태 머신 레이스(Cross-Endpoint TOCTOU) — HIGH"
  DATA-008: "가격/티어 일관성 결여 — HIGH"
  DATA-009: "UGC 콘텐츠 파이프라인 인젝션 — HIGH"
  DATA-010: "RLS/보안규칙 부재 — CRITICAL"
  DATA-011: "마이그레이션 권한 드리프트 — HIGH"
  DATA-012: "DB 트리거 컨텍스트 우회 — HIGH"
```

### Category 4: 기타 실전 취약점

```yaml
점검_항목:
  ETC-001: "Rate Limiting 우회 — MEDIUM"
  ETC-002: "Race Condition / TOCTOU — HIGH"
  ETC-003: "의존성 공급망 공격 — MEDIUM"
  ETC-004: "CI/CD 파이프라인 보안 — MEDIUM"
```

### Category 5: 공격 체인 분석 (Cross-Endpoint Attack Chain)

개별 엔드포인트는 안전하지만 **조합하면 취약해지는 시나리오**를 탐색합니다.

```yaml
점검_절차:
  1_공유_엔티티_매핑: "동일 DB 테이블을 참조하는 모든 엔드포인트 그룹화"
  2_상태_전이_체인: "엔드포인트 A로 상태 변경 → B가 의도치 않은 동작"
  3_권한_에스컬레이션_체인: "일반 기능 조합으로 상위 권한 접근"
  4_콘텐츠_오염_체인: "UGC가 집계/변환을 거쳐 공식 채널에 표시"
  5_자원_고갈_체인: "Rate limit 분산/우회로 시스템 자원 소진"
```

### Category 6: 정보 노출 (Information Disclosure)

```yaml
점검_항목:
  DISC-001: "API 응답 과다 데이터 (SELECT *, JOIN 과다 노출) — MEDIUM~HIGH"
  DISC-002: "PII 노출 (공개 API에 실명/이메일/전화번호) — MEDIUM~HIGH"
  DISC-003: "비즈니스 민감 정보 (수익 배분, 알고리즘 파라미터) — LOW~MEDIUM"
  DISC-004: "JWT 토큰 과다 클레임 — MEDIUM"
  DISC-005: "비활성 엔티티 정보 접근 — MEDIUM"
```

### Category 7: 비즈니스 로직 남용 (Business Logic Abuse)

```yaml
점검_항목:
  BIZ-001: "필수 플로우 단계 스킵 — HIGH"
  BIZ-002: "유료 리소스 무료 접근 — HIGH"
  BIZ-003: "타인 리소스 조작 — HIGH"
  BIZ-004: "엔티티 상태 직접 조작 — HIGH"
  BIZ-005: "비활성 엔티티 남용 — MEDIUM~HIGH"
  BIZ-006: "무제한 리소스 생성 — MEDIUM~HIGH"

  # ─── P2-4 확장: 원자성/결제/경제 공격 ───────────────────────
  BIZ-007: "Single-Packet Atomicity — 동일 요청 N개 병렬 → N회 처리 (CRITICAL)"
  BIZ-008: "Idempotency Key Replay — 같은 key + 다른 body → 이중 처리 (HIGH)"
  BIZ-009: "Coupon Stacking — 쿠폰 A+B+A 재사용으로 누적 할인 (HIGH)"
  BIZ-010: "Email+Alias Bypass — user@x.com vs user+tag@x.com 동치 처리 누락 (MEDIUM)"
  BIZ-011: "Negative Amount — 음수 금액 수용으로 무료/이익 창출 (CRITICAL)"
  BIZ-012: "Currency Rounding — 소수점 절사로 누적 이익 (LOW~MEDIUM)"
  BIZ-013: "State Machine Skip — draft→review→published 흐름에서 published 직행 (HIGH)"
  BIZ-014: "Partial Refund Loop — 부분 환급을 N회 반복 → 원금 초과 환급 (HIGH)"
  BIZ-015: "Airdrop / Free-trial Farming — 동일 디바이스에서 계정 생성 무제한 (MEDIUM)"
```

#### BIZ-007~015 방법론 가이드

```yaml
Single_Packet_Attack:
  원리: |
    HTTP/1.1 또는 HTTP/2 환경에서 동일 state-changing 요청 N개를 하나의
    TCP 세그먼트에 모아 전송 (curl --parallel 또는 Turbo Intruder의
    last-byte sync) → 서버가 순차 처리 전 N개가 거의 동시 도착 →
    read-check-write 사이 race로 잔액/재고/쿠폰 N배 소진 가능.
  대상_시나리오:
    - 잔액 출금 (balance --)
    - 쿠폰 소진 (coupon.used = true)
    - 재고 차감 (stock --)
    - 좋아요/투표 unique 제약
  PoC_Template: |
    # Python asyncio 예시 (3건 병렬)
    import asyncio, aiohttp
    async def one(s): 
      async with s.post(URL, headers=H, json={"amount":100}) as r: 
        return r.status
    async def main():
      async with aiohttp.ClientSession() as s:
        results = await asyncio.gather(*[one(s) for _ in range(3)])
        print(results)
  성공_판정:
    - 서버 응답 3건 모두 200 + 잔액이 3×100만큼 차감 (State Delta)
    - 1건만 성공해야 하는 세마틱이면 원자적 UPDATE/CAS 부재 확정

Idempotency_Replay:
  원리: |
    결제/송금 API가 Idempotency-Key를 받을 때, 같은 key 재요청 시 기존 결과를
    리턴하지 않고 body가 다르면 재처리 → 공격자가 key는 유지하고 body만 바꿔
    2회 과금 가능.
  테스트: |
    1. 1회 결제 요청 (key=X, amount=100) → 200 OK, 거래 1건
    2. 같은 key=X로 amount=1 로 재요청 → 정상이면 200 OK + 기존 거래 리턴
       취약이면 amount=1 신규 거래 생성
    3. State Delta: 거래 건수가 1건 유지되면 정상, 2건이면 취약

Negative_Amount:
  테스트: |
    금액 필드에 -100, "-100", -0.01, -9e99 삽입
    → UI는 차단해도 API가 수용하면 음수 입금/음수 출금 → 이익 창출
  파생: "쿠폰 금액 마이너스, 할인율 120% 입력"

Email_Alias_Bypass:
  테스트: |
    회원가입에서 user@x.com 존재 시 user+tag@x.com, user.@x.com,
    USER@x.com, user@X.com 등이 동일 이메일로 간주되어야 함.
    그렇지 않으면 1인당 1회 쿠폰이 N회 가능.

State_Machine_Skip:
  테스트: |
    draft → review → published의 워크플로우에서 직접 /api/posts/:id
    { status: "published" } PATCH 요청이 수용되는지.
    서버가 현재 status + 허용 전이 매트릭스로 검증해야 함.
```

### Category 8: AI/LLM 공격 (AI/LLM Exploitation)

```yaml
점검_항목:
  AI-001: "직접 프롬프트 인젝션 — 사용자 입력으로 시스템 프롬프트 우회 — HIGH~CRITICAL"
  AI-002: "간접 프롬프트 인젝션 — RAG/DB 데이터로 프롬프트 오염 — HIGH"
  AI-003: "LLM 출력 기반 코드 실행/인젝션 — CRITICAL"
  AI-004: "시스템 프롬프트 추출 — MEDIUM~HIGH"
  AI-005: "민감 데이터 LLM 유출 (PII/시크릿이 프롬프트에 포함) — HIGH"
  AI-006: "에이전트 권한 남용 (승인 없는 도구 호출로 시스템 변경) — HIGH~CRITICAL"
  AI-007: "모델 DoS (의도적 토큰 소진 공격) — MEDIUM"
  AI-008: "RAG 데이터 포이즈닝 (벡터 스토어에 악의적 콘텐츠 주입) — HIGH"
```

### Category 9: 모바일 플랫폼 공격 (Mobile Platform Exploitation)

```yaml
점검_항목:
  MOB-001: "안전하지 않은 로컬 저장소에 자격 증명 저장 — HIGH"
  MOB-002: "Deep Link/URL Scheme 인젝션 — MEDIUM~HIGH"
  MOB-003: "인증서 피닝 미적용 또는 우회 가능 — MEDIUM"
  MOB-004: "네트워크 보안 설정 과도한 예외 (cleartext, ATS 비활성화) — MEDIUM"
  MOB-005: "로컬 DB 암호화 미적용 — MEDIUM~HIGH"
  MOB-006: "민감 데이터 로그 기록 — MEDIUM"
  MOB-007: "생체 인증 로컬 우회 가능 (boolean 체크만) — HIGH"
  MOB-008: "WebView JavaScript 인터페이스 과도한 권한 — HIGH"
  MOB-009: "바이너리 내 하드코딩 시크릿 — HIGH"
```

### Category 10: SDK 오용 및 남용 (SDK Misuse & Abuse)

> SDK 도메인이 활성인 경우에만 수행합니다.
> SDK 제공자 관점에서 소비자의 오용과 공격자의 남용 시나리오를 분석합니다.

```yaml
점검_항목:
  # Secure Defaults (안전한 기본값)
  SDK-001: "기본 설정이 안전하지 않음 (HTTP 허용, 인증서 검증 비활성화 등) — HIGH"
  SDK-002: "디버그 로깅이 릴리즈에서 기본 활성화 — 민감 정보 노출 — HIGH"
  SDK-003: "위험 옵션(disableSsl, debugMode) 활성화 시 경고/차단 없음 — MEDIUM"

  # Credential Management (자격 증명 관리)
  SDK-004: "API 키/토큰이 로그, 에러 메시지, toString()에 노출 — HIGH"
  SDK-005: "자격 증명이 비암호화 로컬 저장소에 저장 — HIGH"
  SDK-006: "SDK 해제 시 메모리/로컬 저장소에 자격 증명 잔류 — MEDIUM"

  # API Surface (공개 API 표면)
  SDK-007: "내부 전용 API가 외부에서 접근 가능 (접근 제어 누락) — HIGH"
  SDK-008: "초기화 미완료 상태에서 API 호출 가능 — 인증 우회 — CRITICAL"
  SDK-009: "설정 객체 참조가 외부에서 변경 가능 — 런타임 설정 조작 — HIGH"
  SDK-010: "Deprecated 비안전 API가 경고/차단 없이 동작 — MEDIUM"

  # Data Flow (데이터 흐름)
  SDK-011: "SDK가 문서화되지 않은 데이터를 백엔드에 자동 전송 — MEDIUM~HIGH"
  SDK-012: "백엔드 응답의 다른 사용자 민감 정보가 개발자 콜백으로 전달 — HIGH"
  SDK-013: "SDK 로컬 캐시에 민감 데이터 평문 잔류 — 앱 삭제 후에도 — HIGH"

  # Network Security (네트워크 보안)
  SDK-014: "HTTPS 실패 시 HTTP 폴백 — 전송 보안 하향 — CRITICAL"
  SDK-015: "인증 실패 시 비인증 폴백 — 인증 우회 — CRITICAL"
  SDK-016: "재시도 로직에 지수 백오프 없음 — 서버 과부하 유발 — MEDIUM"
  SDK-017: "Certificate Pinning 미지원 / MITM 공격 취약 — MEDIUM~HIGH"

  # Resource Management (리소스 관리)
  SDK-018: "무한 재시도 / 무제한 폴링으로 배터리/네트워크 소진 — MEDIUM"
  SDK-019: "캐시/로컬 저장 크기 제한 없음 — 저장공간 소진 — LOW~MEDIUM"
  SDK-020: "연결(WebSocket, TCP) 미해제 — 리소스 누수 — MEDIUM"

  # Distribution (배포)
  SDK-021: "배포 산출물에 소스맵/심볼/디버그 정보 포함 — 내부 구조 노출 — MEDIUM"
  SDK-022: "아티팩트 서명 미적용 — 공급망 공격 — HIGH"
  SDK-023: "전이 의존성에 알려진 CVE — 소비자 앱 전체에 영향 — HIGH"

점검_절차:
  1_Secure_Default_Audit: |
    SDK 초기화 코드를 분석하여 모든 기본값을 열거하고,
    각 기본값이 "가장 안전한 설정"인지 평가한다.
    개발자가 명시적으로 보안을 낮추지 않는 한
    기본 상태에서 안전해야 한다.

  2_Credential_Lifecycle_Trace: |
    자격 증명이 SDK 내부에서 거치는 전체 생명주기를 추적:
    수신 → 저장 → 사용(요청 포함) → 갱신 → 폐기
    각 단계에서 노출/유출 경로를 식별한다.

  3_API_Surface_Enumeration: |
    export/public으로 노출된 모든 API를 열거하고,
    의도치 않은 내부 API 노출, 초기화 순서 우회,
    설정 조작 가능성을 분석한다.

  4_Data_Flow_Mapping: |
    개발자→SDK, SDK→백엔드, 백엔드→SDK→개발자 3방향
    데이터 흐름을 매핑하고, 각 경로에서
    민감 데이터 노출/수집/잔류를 분석한다.

  5_Network_Resilience: |
    네트워크 장애, MITM, 서버 점검 등 비정상 상황에서
    SDK의 폴백/재시도 동작이 보안을 하향시키는지 분석한다.

  6_Distribution_Audit: |
    빌드 산출물의 내용, 서명, 의존성을 감사하여
    공급망 공격 경로와 정보 노출을 식별한다.
```

---

## Phase 3.5: 창의적 공격 추론 (Creative Attack Reasoning)

> Phase 1~3의 체크리스트 기반 분석이 완료된 후,
> 체크리스트에 없는 이 프로젝트 고유의 공격 시나리오를 자유 추론합니다.

```yaml
Creative_Attack_Reasoning:
  목적: |
    Phase 3까지는 알려진 취약점 카테고리(AUTH, TAMP, DATA 등)를 탐색한다.
    이 단계는 카테고리에 포함되지 않는 프로젝트 고유의 공격 가능성을
    공격자의 관점에서 자유롭게 추론한다.

  접근_방식:
    Asset_Driven: |
      "이 시스템에서 가장 가치 있는 자산은 무엇인가?"
      → 자산을 식별하고, 그 자산을 탈취/변조/파괴하는 경로를 역추적한다.
      예: 자금, 개인키, 사용자 데이터, 비즈니스 로직 상태, API 크레딧
    Weakness_Composition: |
      "Phase 1~3에서 발견된 개별 약점들을 비자명하게 조합하면 어떤 시나리오가 가능한가?"
      → 개별적으로는 MEDIUM이지만 조합하면 CRITICAL이 되는 체인을 탐색한다.
      Phase 2 Attack_Chain_Analysis의 7개 체인 유형에 한정되지 않는다.
    Architecture_Specific: |
      "이 아키텍처에서만 가능한 공격이 있는가?"
      → 기술 스택, 배포 모델, 데이터 흐름의 고유 특성에서 발생하는 공격을 추론한다.
      예: 마이크로서비스 간 내부 통신 신뢰, 이벤트 소싱의 재생 공격,
          서버리스 콜드 스타트 타이밍 차이, 멀티테넌트 캐시 키 충돌
    Defender_Blind_Spot: |
      "개발자가 예상하지 못했을 공격 경로가 있는가?"
      → 정상 사용 흐름에서 벗어나되, 시스템이 기술적으로 허용하는 경로를 탐색한다.
      예: API 스펙에 없지만 서버가 수용하는 파라미터, 문서화되지 않은 엔드포인트,
          에러 핸들링 경로에서만 도달하는 코드, 마이그레이션 중 발생하는 일시적 상태

  실행_절차:
    1_자산_식별: "코드 분석에서 파악된 핵심 자산 3~5개를 열거한다"
    2_공격_목표_설정: "각 자산에 대해 '탈취/변조/서비스 거부' 목표를 설정한다"
    3_경로_추론: |
      목표 달성을 위한 공격 경로를 자유롭게 추론한다.
      Phase 3 체크리스트와 중복되는 단순 반복은 금지한다.
      코드에서 경로의 실현 가능성을 확인하되, 확증 없이 단정하지 않는다.
    4_시나리오_기록: |
      도출된 시나리오를 아래 구조로 기록한다:
      Creative_Attack_Scenarios:
        - scenario_id: "CAS-{NNN}"
          target_asset: "[공격 대상 자산]"
          attack_goal: "[목표: 탈취/변조/거부]"
          attack_path: "[공격 경로 설명]"
          related_findings: ["F-XXX", "F-YYY"]
          feasibility: "Likely | Possible | Speculative"
          evidence: "[코드 근거 file:line 또는 추론 근거]"

  제약:
    - "Phase 3 체크리스트 항목의 단순 반복 금지"
    - "최소 1개의 시나리오를 도출 시도해야 함"
    - "시나리오가 없으면 '없음 — 추가 공격 경로 미식별'로 기록, 억지 생성 금지"
    - "feasibility: Speculative인 시나리오는 보고서에 포함하되 심각도를 부여하지 않음"
    - "feasibility: Likely/Possible인 시나리오는 Phase 4에서 POC 생성 대상"

  Phase_3_체크리스트와의_관계: |
    Phase 3은 "알려진 취약점 유형을 이 프로젝트에서 찾는" 연역적 접근이다.
    Phase 3.5는 "이 프로젝트의 구조에서 어떤 공격이 가능한가"를 묻는 귀납적 접근이다.
    둘은 상호 보완적이며, Phase 3.5는 Phase 3을 대체하지 않는다.
```

---

## Phase 3.8: Pentest Routing Plan

> VA/Verifier 후보를 실제 모의해킹 시나리오로 라우팅합니다.
> 실행하지 못한 시나리오도 결과이며, blocker와 다음 조건을 기록해야 합니다.
> `poc` shortcut도 이 Phase를 건너뛰지 않습니다. POC 작성 전 safety_class와
> 승인 필요 여부를 먼저 확정해야 합니다.

```yaml
Pentest_Routing_Plan:
  입력:
    - "raw_findings_ledger_path (templates/raw-findings-ledger.template.yaml)"
    - "va_findings_index_path"
    - "pending_verification.PENTEST"
    - "target_url"
    - "auth/test-data context (제공 시)"
  출력:
    - "engagement_dir/06_pentest_plan.yaml 또는 0N_va_pentest_plan-<round>.yaml"
    - "# VA plan의 라운드별 접두(va-auditor.md storage 기준): 1차=01_va_pentest_plan-1st.yaml, 2차=03_va_pentest_plan-2nd.yaml"
  스키마: "templates/pentest-plan.template.yaml"

  동일_취약점_Instance_규칙:
    목적: |
      Pentest는 같은 취약점이 여러 endpoint/flow에서 재현되는지 검증할 수 있지만,
      root cause와 remediation이 동일하면 새 Finding으로 발행하지 않는다.
      대표 Finding의 affected_instances에 라이브 증거를 붙인다.
    finding_relationship:
      PRIMARY_FINDING: "대표 Finding 자체 검증"
      SAME_ROOT_CAUSE_INSTANCE: "같은 control failure/remediation/root cause의 추가 영향 대상 검증"
      NEW_CANDIDATE: "root cause/remediation이 달라 새 후보로 승격"
      REGRESSION_CHECK: "수정 후 재발 여부 확인"
    출력_규칙:
      - "scenario에는 finding_relationship을 기록하고, 동일성 판단 근거를 objective/expected_evidence에 남긴다"
      - "SAME_ROOT_CAUSE_INSTANCE는 affected_instance(type,target,evidence,exploitability)를 필수 기록"
      - "TESTED_VULNERABLE이어도 같은 취약점 맥락이면 새 Finding이 아니라 대표 Finding에 병합"
      - "root cause가 다르거나 remediation이 다를 때만 NEW_CANDIDATE로 raw ledger에 추가"

  라우트:
    LIVE_UNAUTH: "인증 없이 안전하게 검증 가능"
    LIVE_AUTH_LOW_PRIV: "GUEST/VIEWER 등 낮은 권한 계정 필요"
    LIVE_AUTH_ROLE_SPECIFIC: "CS/RISK/FINANCE/SUPER_ADMIN 등 역할별 계정 필요"
    LIVE_BUSINESS_FLOW: "테스트 데이터와 다단계 업무 흐름 필요"
    EXTERNAL_SYSTEM_REQUIRED: "repo 밖 서비스, worker, gateway, callback consumer 필요"
    CONFIG_REVIEW_ONLY: "라이브 공격보다 설정/코드 리뷰로 판단"
    NOT_SAFE_WITHOUT_APPROVAL: "명시 승인 없이 실행 금지"

  안전_등급:
    SAFE_READ_ONLY: "GET/HEAD/OPTIONS 등 읽기 전용"
    SAFE_VALIDATION_ONLY: "빈 body/invalid body 등 상태 변경 없는 검증"
    STAGING_MUTATION: "staging 테스트 데이터에 한정한 상태 변경"
    REQUIRES_TEST_DATA: "전용 테스트 리소스 필요"
    REQUIRES_EXPLICIT_APPROVAL: "명시 승인 필요"
    DO_NOT_RUN_PROD: "프로덕션 실행 금지"

  상태:
    READY: "전제조건 충족, 실행 가능"
    TESTED_PASS: "테스트 완료, 취약하지 않음"
    TESTED_VULNERABLE: "테스트 완료, 취약 확인"
    TESTED_PARTIAL: "일부 변형만 성공/차단"
    BLOCKED_NO_AUTH: "필요 계정/토큰 없음"
    BLOCKED_NO_TEST_DATA: "테스트 리소스 없음"
    BLOCKED_OUT_OF_SCOPE_SERVICE: "외부 시스템 범위 밖"
    NOT_SAFE_WITHOUT_APPROVAL: "승인 전 실행 금지"
    NOT_TESTED: "기타 사유로 미실행"

  필수_시나리오_패밀리:
    Role_Matrix:
      목적: "역할별 접근 제어와 데이터 노출 검증"
      roles: ["GUEST", "VIEWER", "CS_ADMIN", "RISK_ADMIN", "FINANCE_ADMIN", "SUPER_ADMIN"]
    Business_Flow:
      목적: "실제 업무 흐름에서 취약점 성립 여부 확인"
      examples:
        - "merchant callbackUrl 저장 → 안전한 callback trigger → controlled listener 수신 확인"
        - "role demotion → 기존 세션으로 권한 유지 여부 확인"
        - "blocklist 역전 날짜 저장 → 정책 적용 여부 확인"
        - "webhook log raw header/body 접근 → 민감 필드 노출 확인"
    Session_Cookie:
      목적: "로그인 후 Set-Cookie와 세션 캐시/권한 반영 확인"
      examples:
        - "Secure/HttpOnly/SameSite/Domain 확인"
        - "역할 변경 후 cookieCache 만료 전 접근 가능성 확인"
    External_Integration:
      목적: "repo 밖 소비자가 필요한 후보를 pending으로 보존"
      examples:
        - "callback worker/payment processor"
        - "email rendering pipeline"
        - "API gateway/WAF/rate limiter"
    OAST_Controlled:
      목적: "외부 callback/SSRF류를 안전한 listener로만 확인"
      allowed: ["https://controlled-listener.example/{nonce}"]
      prohibited:
        - "127.0.0.1"
        - "169.254.169.254"
        - "RFC1918/private/internal ranges"

  게이트:
    - "PENDING_PENTEST 후보는 반드시 pentest plan scenario를 가진다"
    - "동일 취약점 맥락의 검증 결과는 대표 Finding의 affected_instances에 병합한다"
    - "실행하지 못한 scenario는 blocker와 next_step을 기록한다"
    - "Sweep FAIL만으로 TESTED_VULNERABLE 확정 금지 — Route A~F 심층 검증 필요"
    - "프로덕션 URL에서는 STAGING_MUTATION/REQUIRES_TEST_DATA 시나리오 실행 금지"
```

---

## Phase 4: POC 생성

**선행 조건**: Phase 3.8 Pentest Routing Plan 완료. `poc` shortcut은
Phase 3.8 → Phase 4 → Phase 4.5만 실행한다.

### POC 생성 규칙

```yaml
생성_규칙:
  간단한_취약점:
    조건: "단일 HTTP 요청 또는 간단한 코드로 검증 가능"
    형태: "보고서 내 인라인 코드 블록 (curl 또는 코드 스니펫)"

  복잡한_취약점:
    조건: "다단계 시나리오, 상태 관리, 동시성 테스트 필요"
    형태: "독립 실행 가능한 스크립트 파일 (poc/ 디렉토리)"

  실행_모드:
    dry_run: "기본 모드. 구조 분석만, 실제 요청 미전송"
    live: "--url 옵션 사용 시에만 실제 HTTP 요청 전송"

  안전_원칙:
    - "파괴적 작업 POC는 반드시 주석으로 경고"
    - "프로덕션 환경 대상 POC는 읽기 전용 검증만"
    - "모든 POC에 롤백/정리 절차 포함"
```

### POC 포함 요소

```yaml
POC_구조:
  1_취약점_설명: "F-ID, 차원, 공격 시나리오"
  2_전제_조건: "필요한 인증 토큰/계정, 대상 URL, 환경"
  3_실행_코드: "dry-run(기본) / live 모드"
  4_성공_판정_기준: "예상 응답, 취약/안전 비교, 자동 Pass/Fail"
  5_수정_가이드: "코드 수정 방향, 보안 패턴, 참조 문서"
```

---

## Phase 4.5: 분석 결과 자체 검증 (Self-Verification)

> 모든 모드(dry-run / live)에서 실행됩니다.
> Phase 1~5에서 도출된 Finding을 보고서에 기록하기 전에 자체 검증합니다.
> `poc` shortcut에서도 Phase 4.5는 필수입니다.

```yaml
Self_Verification:
  목적: |
    분석 결과의 오탐(과대 평가)과 미탐(누락)을 최소화한다.
    각 Finding에 대해 아래 3단계를 실행한다.

  Step_1_도달_가능성_검증:
    설명: "취약 코드가 실제 실행 경로에서 호출되는가?"
    절차:
      - "취약 함수/메서드의 호출자(caller)를 코드 전체에서 검색"
      - "호출자 0건 → Dead Code 태그, 심각도 재평가"
      - "호출자 존재 → 호출 경로(entry point → ... → 취약 함수)를 기록"

  Step_2_보상_제어_확인:
    설명: "다른 레이어에서 동일 위협을 차단하는 보상 제어가 있는가?"
    프로토콜: "common/compensating-control.md의 4단계 프로토콜을 실행한다."
    절차:
      - "Step 1: 위협 경로의 모든 레이어를 순회한다"
      - "Step 2: 각 레이어에서 후보 보상 제어를 식별한다"
      - "Step 3: 5개 질문(범위/정밀도/우회가능성/완전성/독립성)으로 유효성을 검증한다"
      - "Step 4: Effective_Complete/Effective_Narrow/Partial/Ineffective/Unverifiable로 판정하고 기록한다 (compensating-control.md Step 4가 정본)"
    원칙:
      - "보상 제어의 존재 ≠ 위협 차단 — 유효성이 코드에서 입증되어야 한다"
      - "Effective_Complete(1단계 하향)/Effective_Narrow(0.5단계 하향+태그) 판정 외에는 원래 심각도를 유지한다"

  Step_3_로컬_PoC_검증:
    설명: "코드 분석 결론을 로컬 실행으로 확인 가능한가?"
    조건: "라이브 환경 접근 없이, 대상 코드를 로컬에서 실행 가능한 경우"
    절차:
      - "SDK/라이브러리: 의존성 설치 후 취약 함수를 직접 호출하는 스크립트 작성"
      - "독립 함수: 함수 로직을 재현하는 최소 스크립트로 동작 확인"
      - "설정 기반: 설정 파일/환경 변수 조합으로 위험 동작 재현"
    예시:
      JWT_미검증: |
        jose 라이브러리의 decodeJwt()에 alg:none 위조 토큰을 전달하여
        valid=true 반환 여부를 로컬에서 확인
      JWT_알고리즘_혼동_HS_RS: |
        RS256으로 발급된 토큰을 HS256으로 검증하는 경로에 대해,
        IdP 공개키(PEM)를 HMAC 시크릿으로 사용하여 서명한 토큰이
        수용되는지 로컬 PoC로 확인:
        ```python
        import jwt
        pubkey = open("idp.pem").read()
        forged = jwt.encode({"sub":"admin"}, pubkey, algorithm="HS256")
        # 대상 검증기가 수용하면 → HS/RS 혼동 취약
        ```
      JWT_kid_경로_주입: |
        kid 헤더에 `../../dev/null` 또는 `../../tmp/attacker.key`를 넣어
        검증기가 해당 경로를 키로 로드하는지 확인 (file read / RCE 전제).
      JWT_jku_조작: |
        jku 헤더를 공격자 호스팅 JWKS URL로 설정하고, 해당 jwks에서
        자신의 공개키로 위조 서명 검증이 통과하는지 확인.
        jwks_uri allowlist 없을 시 취약.
      OAuth_state_재사용: |
        authorize 요청 2회로 state=A를 재수집 → 2번째 callback에 이전 state를
        재사용하여 CSRF/계정 바인딩 공격 가능한지 확인.
      OAuth_redirect_uri_우회: |
        등록된 `https://app.example.com/callback`에 대해 다음 변형을 시도:
        - https://app.example.com.attacker.com/callback
        - https://app.example.com/callback/../admin
        - https://app.example.com/callback?x=https://attacker.com
        - https://app.example.com@attacker.com/callback
        성공 시 authorization code 탈취 가능.
      로깅_유출: |
        프로덕션 모드(IS_DEV=false)에서 커스텀 로거 주입 후
        민감 데이터 캡처 여부를 로컬에서 확인
      설정_변조: |
        SDK 인스턴스의 config 객체를 외부에서 교체 가능한지
        Object.isFrozen() 등으로 로컬 확인
    판정:
      로컬_재현_성공: "Locally Verified — 코드 분석 결론 뒷받침"
      로컬_재현_실패: "코드 분석 결론 재검토 — 오탐 가능성"
      로컬_실행_불가: "Code Review Only — 로컬 검증 불가 명시"

  적용_우선순위: |
    모든 Finding에 Step 1~2는 필수. Step 3은 CRITICAL/HIGH Finding에 권장.
    LOW/MEDIUM은 Step 1~2만으로 충분.
```

---

## Phase 6.0: 엔드포인트 전수 스윕 (Endpoint Sweep)

> `--url` 옵션이 제공된 경우, Phase 6 Finding 검증 **이전에** 실행됩니다.
> Phase 0-4 엔드포인트 인벤토리의 **모든 외부 표면**을 대상으로 기본 보안 테스트를 수행합니다.

### 목적과 위치

```yaml
목적: |
  코드 분석(Phase 1~5)은 "발견된 취약점"만 Phase 6에 전달한다.
  코드 분석이 놓친 취약점이 있는 엔드포인트는 Phase 6에서도 테스트되지 않는다.
  Phase 6.0은 이 구조적 갭을 해소한다:
  - Phase 0-4 인벤토리의 모든 엔드포인트에 Finding 유무와 무관하게 기본 테스트 실행
  - 코드 분석에서 놓친 런타임 취약점 발견 (미들웨어 순서, 프레임워크 기본 엔드포인트 등)
  - Sweep에서 발견된 이상 항목은 Phase 6 Route A~F에 주입하되 기존 후보와 같은 취약점 맥락인지 검토
  - 기존 후보와 같은 control failure/remediation/root cause면 신규 Finding이 아니라 affected_instance로 병합

실행_순서: |
  Test_Context_Collection (기존) → Phase 6.0 Sweep → Phase 6 Finding 검증 (Route A~F)
  Sweep 결과의 신규 Finding 후보는 Phase 6 Route에 추가되어 심층 검증된다.

입력: |
  - Phase 0-4: API 엔드포인트 인벤토리 (전체 목록 + AUTH 태깅)
  - Phase 0-3: Attack Surface Map (Entry_Points, Auth_Topology)
  - Test_Context_Collection에서 수집한 BASE_URL, 인증 토큰
```

### Sweep 카테고리

```yaml
Sweep_1_Auth_Gate_Verification:
  목적: "인증 필수 엔드포인트가 실제로 비인증 요청을 거부하는지 전수 확인"
  입력: "Phase 0-3 Entry_Points 중 AUTH: yes 태깅된 전체 엔드포인트"
  절차:
    1: "각 엔드포인트에 인증 헤더 없이 요청 전송 (GET → GET, POST → POST, 동일 메서드)"
    2: "응답 코드 수집: 401/403 = PASS, 200/201/202/2xx = FAIL, 5xx = ERROR"
    3: "FAIL 항목은 신규 Finding 후보 (AUTH-001: 인증 미들웨어 미적용)"
  판정_주의: |
    200 응답이 반드시 취약은 아님:
    - 공개 API가 코드 분석에서 AUTH: yes로 오태깅된 경우 (FP)
    - 응답 본문이 빈 데이터/제한된 데이터면 부분 보호 가능
    FAIL 항목은 반드시 응답 본문을 확인하여 실제 데이터 노출 여부를 판별한다.
  최적화: |
    엔드포인트 50개 이상 시 샘플링 전략:
    - state-changing (POST/PUT/PATCH/DELETE) 엔드포인트는 전수 테스트
    - read-only (GET) 엔드포인트는 라우트 그룹별 대표 1개 + 랜덤 20% 샘플
    - auth_opt_out_routes (Phase 0-3에서 명시적 제외된 경로)는 전수 테스트

Sweep_2_Method_Probing:
  목적: "정의되지 않은 HTTP 메서드로 요청 시 서버가 적절히 거부하는지 확인"
  입력: "Phase 0-4 인벤토리에서 각 엔드포인트의 정의된 메서드"
  절차:
    1: "각 엔드포인트에 정의되지 않은 메서드 1개를 전송 (GET-only → POST 시도)"
    2: "405 Method Not Allowed = PASS, 200/2xx = FAIL"
    3: "FAIL 중 state-changing 메서드(POST/PUT/PATCH/DELETE) 성공 시 → 신규 Finding 후보"
  범위_제한: |
    - GET-only 엔드포인트에 DELETE/PUT 시도 (최대 위험)
    - 이미 POST+GET이면 PATCH/DELETE 시도
    - OPTIONS/HEAD는 스킵 (일반적으로 무해)
  판정_주의: |
    프레임워크가 모든 메서드를 동일 핸들러로 라우팅하는 경우 (예: Next.js route.ts)
    코드 내부에서 method 분기 여부를 Phase 1~3 코드 분석 결과와 대조한다.

Sweep_3_Hidden_Endpoint_Discovery:
  목적: "Recon이 추론한 자동 노출 엔드포인트(Auto_Exposed_Endpoints)를 라이브로 검증"

  입력: |
    Phase 0 Recon의 Auto_Exposed_Endpoints 결과를 그대로 사용한다.
    Sweep_3은 자율 추론을 수행하지 않는다 (재현성 보장 + 책임 분리).
    상세: skills/ch015/common/recon.md → Phase 0-4 → Auto_Exposed_Endpoints_Inference

  원칙:
    No_Inference_Here: |
      "엔드포인트 추론은 Recon의 책임. Sweep_3는 검증만 수행.
       Recon이 못 잡은 후보를 Sweep_3가 자체 추론하면 재현성이 무너진다."
    Reproducibility: |
      "동일 프로젝트 재실행 시 동일 후보 검증. AI 변동성 차단."

  절차:
    1_입력_확인: |
      Recon 출력의 Auto_Exposed_Endpoints 목록 로드.
      비어있으면 → '미감지 — Recon 보강 필요' 경고 출력 후 Sweep_3 종료.
    2_프로빙: |
      각 후보 path에 GET 요청 전송 (인증 없이 / 있으면 표준 인증으로).
    3_응답_분석: |
      200 응답 시 본문 분석:
      - 민감 정보 포함 (스택 트레이스, 환경변수, 내부 구조, API 명세, 사용자 데이터 등)
      - 프레임워크 정보 노출 (버전, 배포 환경)
    4_Finding_생성: |
      민감 정보 노출 확인 시 신규 Finding 후보 (F-S{NNN}).
      Recon 출력의 evidence(의존성/설정 file:line)를 Finding 증거에 포함.

  Recon_미보강_경고: |
    Auto_Exposed_Endpoints가 비어있거나 명백히 불충분해 보이면:
    1) Sweep_3 결과에 'Recon Auto_Exposed_Endpoints inference 보강 필요' 경고 명시
    2) Sweep_3 자체 추론은 금지 — 추론 책임은 Recon에만 있음
    3) Lead/CISO에게 Recon 재실행 권고 가능

  안전: "GET 요청만. state-changing 프로빙 금지."

  ⚠️_철학:
    Single_Source_of_Truth: "엔드포인트 발견은 Recon, 보안 검토는 VA, 라이브 검증은 Sweep_3 — 책임 명확 분리"
    No_Pattern_List_Dependency: "고정 카탈로그 의존하지 않음. 프레임워크 가변성은 Recon AI 추론으로 대응"
    Verification_Not_Inference: "Sweep_3는 추론이 아닌 검증 단계 — Recon 결과를 신뢰하고 라이브로 확인"

Sweep_4_Security_Header_Baseline:
  목적: "전체 애플리케이션의 보안 헤더 적용 현황을 표본 검사"
  절차:
    1: "대표 엔드포인트 3~5개 선정 (메인 페이지, API 루트, 인증 엔드포인트)"
    2: "HEAD 요청으로 응답 헤더 수집"
    3: "누락 헤더 체크: CSP, X-Frame-Options, HSTS, X-Content-Type-Options"
    4: "전체 누락 시 단일 Finding (엔드포인트별 개별 Finding 생성 금지)"
  판정: |
    보안 헤더 부재 자체는 MEDIUM 이하.
    Phase 1~5에서 XSS/Clickjacking Finding이 있는 경우에만 심각도 연계.

Sweep_5_CORS_Misconfiguration:
  목적: "Origin 반사 또는 와일드카드 허용으로 인한 교차 출처 공격 가능성 확인"
  절차:
    1: "대표 API 엔드포인트 3~5개에 Origin: https://attacker.example.com 헤더 전송"
    2: "Access-Control-Allow-Origin 응답 헤더 확인"
    3: |
      - 공격자 Origin 그대로 반사 → FAIL (credential 포함 시 CRITICAL)
      - * (와일드카드) → 조건부 FAIL (withCredentials 가능 여부에 따라)
      - 고정 허용 목록 → PASS
  추가_변형: |
    반사가 감지되면 추가 테스트:
    - null Origin (data: URI, sandboxed iframe)
    - 서브도메인 변형 (trusted.com.attacker.com)
    - 프로토콜 다운그레이드 (http:// Origin)
```

### Sweep 결과 처리

```yaml
결과_분류:
  SWEEP_PASS: "기대대로 동작 — 추가 조치 없음"
  SWEEP_FAIL: "이상 탐지 — 신규 Finding 후보"
  SWEEP_ERROR: "네트워크/서버 에러 — 재시도 1회 후 기록"

신규_Finding_생성:
  절차:
    1: "Sweep FAIL 항목을 유형별로 그룹화"
    2: "각 그룹에 대해 코드 분석 결과(Phase 1~5)와 대조"
    3: |
      - 코드 분석에서 이미 Finding으로 보고됨 → 기존 Finding에 라이브 증거 추가
      - 코드 분석에서 미발견 → 신규 Finding 후보 생성 (F-S001~)
    4: "신규 Finding 후보는 Phase 6 Route A~F에 주입하여 심층 검증"
  Finding_ID: "Sweep 발견 Finding은 F-S{NNN} 접두사로 구분 (F-S001, F-S002, ...)"
  주의: |
    Sweep은 기본 테스트(shallow)이므로 FAIL = 즉시 취약점이 아니다.
    반드시 Phase 6 Route의 State Delta 검증, Differential Testing 등으로
    심층 확인한 후에만 최종 Finding으로 확정한다.

결과_요약_형식: |
  ```
  ┌──────────────────────────────────────────────────────────────┐
  │ ENDPOINT SWEEP RESULT                                        │
  ├──────────────────────────────────────────────────────────────┤
  │ 총 엔드포인트:    {total}                                     │
  │ 테스트 완료:      {tested}                                    │
  │ PASS:            {pass}                                      │
  │ FAIL (후보):      {fail} → Phase 6 심층 검증 대상             │
  │ ERROR:           {error}                                     │
  ├──────────────────────────────────────────────────────────────┤
  │ Sweep 카테고리별:                                             │
  │   Auth Gate:     {s1_pass}/{s1_total} PASS                   │
  │   Method Probe:  {s2_pass}/{s2_total} PASS                   │
  │   Hidden EP:     {s3_found}건 발견                            │
  │   Security Hdr:  {s4_missing}종 누락                          │
  │   CORS:          {s5_pass}/{s5_total} PASS                   │
  ├──────────────────────────────────────────────────────────────┤
  │ 신규 Finding 후보: {new_candidates}건 → Phase 6 Route 주입    │
  └──────────────────────────────────────────────────────────────┘
  ```
```

### 안전 원칙 (Phase 6 공통 적용 + Sweep 추가)

```yaml
Sweep_안전:
  - "모든 Sweep은 읽기 전용 — state-changing 요청은 Sweep_1의 기존 메서드 재현만"
  - "Sweep_1의 POST/PUT/PATCH/DELETE는 빈 body 또는 최소 body로 전송 (실제 변경 방지)"
  - "프로덕션 감지 시 Sweep_1은 GET 엔드포인트만 테스트, state-changing은 스킵"
  - "요청 간 100ms 이상 간격 유지 (서버 과부하 방지)"
  - "5xx 응답 연속 3회 발생 시 해당 Sweep 카테고리 중단 + 사용자 알림"
  - "Phase 6 공통 안전 원칙(프로덕션 감지, Rate Limit 제한)이 동일 적용"
```

---

## Phase 6: 라이브 검증 (Live Verification)

> `--url` 옵션이 제공된 경우에만 실행됩니다.
> Phase 6.0 Sweep 완료 후, Finding 기반 심층 검증을 수행합니다.

### 인증 자동 구성

```yaml
자동_구성:
  Supabase:
    프로젝트_레퍼런스_추출: "코드에서 SUPABASE_URL 탐색 → project_ref 추출"
    쿠키_이름: "sb-{project_ref}-auth-token"
    쿠키_값: "raw JSON (base64 인코딩 안 함)"
    토큰_검증: "인증 필수 엔드포인트에 테스트 요청"

  일반:
    Bearer_토큰: "Authorization: Bearer {token} 헤더"
    API_Key: "X-API-Key: {key} 헤더"
```

### 검증 분류

```yaml
검증_분류:
  무인증_검증: "인증 없이 검증 가능 (보안 헤더, 무인증 접근, Rate Limit)"
  인증_필요_검증: "유효한 세션/토큰 필요 (비즈니스 로직 결함)"
  API_키_검증: "외부 API 키 필요"
  검증_불가: "서버 내부 상태 의존 (코드 리뷰만 가능)"
```

### 판정 기준

```yaml
판정:
  CONFIRMED: "실제 악용 가능 확인됨 — 상태 변경이 증거로 입증됨"
  BLOCKED: "다른 방어 계층에 의해 차단됨"
  MITIGATED: "존재하나 영향 제한적"
  BLIND_ACCEPT: "API가 성공 응답을 반환하나, 실제 상태 변경 없음 (fire-and-forget 패턴)"
  INCONCLUSIVE: "네트워크/타임아웃으로 판정 불가"
  NOT_TESTED: "키 미제공 또는 검증 불가능"
```

### 판정 규칙: 응답 vs 실제 효과

```yaml
판정_규칙:
  핵심_원칙: |
    "API 응답 코드/메시지만으로 취약점을 판정하지 않는다.
     반드시 대상 시스템의 상태 변경(State Delta)을 독립적으로 검증해야 한다."

  State_Delta_검증:
    정의: "POC 실행 전후의 대상 리소스 상태를 비교하여 실제 효과 확인"
    절차:
      1: "POC 실행 전 대상 리소스의 상태 스냅샷 기록 (GET 요청)"
      2: "POC 실행 (POST/PUT/PATCH/DELETE)"
      3: "충분한 대기 시간 후 상태 재조회 (비동기 처리 고려)"
      4: "전후 스냅샷 diff 분석"
    판정:
      diff_존재: "CONFIRMED — 실제 상태 변경 발생"
      diff_없음_성공응답: "BLIND_ACCEPT — 응답만 성공, 실제 효과 없음"
      diff_없음_실패응답: "BLOCKED — 서버에서 명시적 거부"

  비동기_처리_대기:
    설명: "fire-and-forget, 큐, 배치 처리 등 비동기 아키텍처 고려"
    절차:
      - "대상 시스템의 비동기 처리 주기를 코드/설정/문서에서 파악"
      - "처리 주기 × 3 이상 대기하며 최소 3회 폴링으로 상태 재조회"
      - "처리 주기 불명 시: 1초, 5초, 30초 지수 간격으로 폴링"
      - "폴링 기간 중 변화가 없으면 최종 판정"
```

### 검증 기법

```yaml
기법_1_Differential_Testing:
  목적: "동일 액션을 인증/비인증으로 각각 실행하여 실제 차이를 비교"
  핵심_절차:
    - "테스트 대상 액션을 정확히 동일하게 정의"
    - "비인증 요청 전송 → 응답 기록 + 상태 조회 (비동기 API는 처리 주기 맞춰 폴링)"
    - "인증 요청 전송 → 동일 기준으로 응답 기록 + 상태 조회"
    - "응답 코드 + 응답 본문 + 상태 변경 3축 비교"
  판정:
    응답_동일_상태_동일_변경: "CONFIRMED — 인증 없이도 실제 악용 가능"
    응답_동일_상태_인증만_변경: "BLIND_ACCEPT — 응답은 동일하나 비인증은 실제 미적용"
    응답_다름_상태_다름: "BLOCKED — 서버가 명시적으로 구분"
    응답_동일_상태_둘다_미변경: "INCONCLUSIVE — 추가 검증 필요"
  키_미보유_시: "비인증 요청만 전송하되 Control Group 기법과 결합하여 자연 변화와 구분"

기법_2_Control_Group_Observation:
  목적: "시스템의 자연적 상태 변화와 POC에 의한 변화를 구분"
  적용_조건: |
    자율 상태 변화가 있는 시스템(배치 잡, 스케줄러, 이벤트 드리븐, 게임 틱 등)에서만 사용.
    순수 CRUD API처럼 외부 요청 없이 상태가 바뀌지 않는 시스템에서는 불필요.
  절차:
    - "실험군(POC 전송)과 대조군(아무 액션 없음) 동일 환경에서 선정"
    - "시스템 자율 처리 주기에 맞춰 양쪽 상태를 폴링"
  POC_귀인_판정: |
    실험군 변화 - 대조군 변화 패턴 = POC 효과
    - 실험군에서만 POC와 일치하는 특이 변화 발생 → CONFIRMED
    - 양쪽 변화 패턴이 동일 → BLIND_ACCEPT / BLOCKED
    - 양쪽 모두 변화 없음 → 시스템 비활성, 재시도 필요

기법_3_Response_Semantics_Analysis:
  목적: "API 응답의 구조적 특성으로 실제 처리 여부를 추론"
  핵심_신호:
    202_Accepted: |
      ⚠️ 경고 플래그: 비동기 수신 확인(ACK)일 가능성 높음.
      응답 본문에 처리 결과가 없으면 fire-and-forget 의심.
      별도 폴링/조회로 실제 처리 결과 확인 필수.
    최소_응답: |
      {success: true} 또는 {accepted: true}만 반환 → fire-and-forget 의심.
      특히 상태 변경 API에서 이 패턴은 Blind Accept 가능성 높음.
    에러_상세: |
      {error: "UNAUTHORIZED", message: "..."} → 서버가 명시적 거부.
      이 응답이 인증/비인증 모두에서 나오는지 차등 검증.
  Response_Timing: "보조 지표로만 사용. 절대 임계값 판정 금지."

기법_4_Deliberate_Failure_Injection:
  목적: "의도적으로 잘못된 요청을 보내 서버의 검증 수준을 탐지"
  원리: "실제 처리하는 서버는 구체적 에러 반환. fire-and-forget은 잘못된 요청에도 동일 성공 응답."
  테스트_케이스:
    - "Invalid_Target: 존재하지 않는 리소스 ID (기대: 404 vs 202)"
    - "Invalid_Action: 존재하지 않는 액션 타입 (기대: 400 vs 202)"
    - "Impossible_State: 현재 불가능한 액션 (기대: 409 vs 202)"
    - "Malformed_Payload: 필수 필드 누락 (기대: 400 vs 202)"
  종합_판정: |
    - 4개 중 3개 이상에서 동일 성공 응답 → fire-and-forget 확정
    - 각각 구체적 에러 반환 → 실제 처리 확인 (차등 검증으로 진행)
    - 혼합 → 부분적 검증 (Gateway에서 일부 검증, 나머지는 Module)

기법_5_Multi_Step_Attack_Chaining:
  목적: "단일 요청으로 검증 불가한 비즈니스 로직 취약점을 다단계 시나리오로 검증"
  적용_대상:
    - "비즈니스 플로우 우회 (결제 → 승인 → 배송 단계 스킵)"
    - "상태 조작 (리소스 생성 → 권한 변경 → 비인가 접근)"
    - "권한 상승 체인 (일반 가입 → 프로필 수정 → 관리자 기능 접근)"
    - "레이스 컨디션 (동시 요청으로 잔액 이중 사용)"
    - "IDOR 체인 (자원 생성 → ID 추출 → 타 사용자 접근)"
```

### 검증 통합 프로토콜

```yaml
Integrated_Verification_Protocol:
  설명: |
    라이브 검증의 목표별로 적절한 기법을 선택하여 실행하는 프로토콜.
    Finding의 유형에 따라 검증 경로가 분기된다.

  검증_경로_선택:
    Route_A_비동기_응답_의심:
      조건: "API가 202 반환, 또는 {success:true}만 반환하여 실제 처리 여부 불명"
      적용_기법:
        1: "Response Semantics Analysis — 사전 판별"
        2: "Deliberate Failure Injection — fire-and-forget 확정/배제"
        3: "Differential Testing 또는 Control Group — State Delta 확인"
      판정: "CONFIRMED / BLIND_ACCEPT / BLOCKED"

    Route_B_인증_인가_우회:
      조건: "비인증 접근, IDOR, 권한 상승 등 접근 제어 취약점"
      적용_기법:
        1: "Differential Testing — 인증/비인증 또는 사용자A/사용자B 비교"
        2: "Multi-Step Attack Chaining — IDOR/권한 상승 시 다단계 시나리오 적용"
        3: "State Delta 검증 — 실제 상태 변경 확인"
      판정: "CONFIRMED / BLOCKED"

    Route_C_정보_노출:
      조건: "API 응답 과다 데이터, PII 노출, 내부 정보 노출"
      적용_기법:
        1: "대상 API 호출 — 응답 본문에 민감 데이터 포함 여부 확인"
        2: "인증 수준별 비교 — 비인증/일반/관리자 응답 차이"
      판정: "CONFIRMED (민감 데이터 존재) / BLOCKED (필터링 확인)"

    Route_D_비즈니스_로직:
      조건: "플로우 스킵, 레이스 컨디션, 상태 조작 등 비즈니스 결함"
      적용_기법:
        1: "Multi-Step Attack Chaining — 다단계 시나리오 구성 및 변수 바인딩"
        2: "시나리오 템플릿 중 해당 유형 선택 (비즈니스_플로우_스킵, 권한_상승_체인 등)"
        3: "State Delta 검증 — 비즈니스 규칙 위반 상태 도달 여부"
      판정: "CONFIRMED / MITIGATED / BLOCKED"

    Route_E_Rate_Limit_리소스:
      조건: "Rate Limiting, 리소스 소비 제어"
      적용_기법:
        1: "반복 요청 (최대 30회) — 차단 응답(429) 발생 시점 확인"
        2: "차단 후 회복 시간 측정"
      판정: "CONFIRMED (미제한) / MITIGATED (제한 존재하나 우회 가능) / BLOCKED"

    Route_F_VA_Escalation:
      조건: |
        VA에서 Unverifiable_HTTP (verification_target: PENTEST)로 분류된
        보상 제어가 있는 Finding. offsec-lead가 Pending_Verification 목록에서
        PENTEST 대상 항목을 전달한 경우.
      목적: |
        VA 코드 분석에서 확인 불가했던 보상 제어의 실제 차단 효과를
        라이브 HTTP 요청으로 검증하여 FP를 줄인다.
      입력: |
        Pending_Verification.PENTEST 목록:
          - finding_id, control, claim, unverifiable_reason
      적용_기법:
        1_보상_제어_대상_식별: |
          VA가 전달한 claim(검증 대상)을 기반으로 보상 제어의 주장을 파악한다.
          테스트 방법은 VA가 지시하지 않으며, Pentest가 Attacker_Mindset으로
          자율적으로 결정한다.
          - claim에 대해 "이 제어를 어떻게 우회할 수 있는가?"를 질문한다
          - 단일 페이로드/요청이 아닌 다양한 변형으로 제어의 실효성을 시험한다
          - 기존 Route_A~E 기법을 보상 제어 유형에 맞게 조합 적용한다
        2_차단_검증: |
          보상 제어가 주장하는 차단을 실제 HTTP 요청으로 시도한다.
          - 보상 제어가 차단해야 할 요청 → 차단 응답 확인 (403, 429, 401 등)
          - 보상 제어가 허용해야 할 요청 → 정상 응답 확인 (200, 201 등)
        3_State_Delta: |
          차단 응답이 실제 차단인지 확인 (Route_A 기법 병용):
          - 차단 응답 + State Delta 없음 → 실제 차단
          - 차단 응답이지만 State Delta 존재 → 차단 우회 가능
      판정:
        BLOCKED: |
          보상 제어가 실제로 위협을 차단함을 라이브로 확인.
          → 보상 제어 판정을 Unverifiable → Effective_Complete로 재분류
            (라이브 차단 증거 + 기존 코드/설정 증거로 Observed 증거 2개 이상일 때.
             라이브 증거 단독이거나 scope가 제한적이면 보수적으로 Effective_Narrow).
          → Effective_Complete는 심각도 1단계 하향 근거,
            Effective_Narrow는 0.5단계 하향 + narrow 태그 (compensating-control.md Step 4).
        CONFIRMED: |
          보상 제어가 위협을 차단하지 못함을 라이브로 확인.
          → VA Finding의 심각도 유지.
          → 보상 제어 판정을 Unverifiable → Ineffective로 재분류.
        PARTIAL: |
          보상 제어가 일부 변형만 차단.
          → VA Finding의 심각도 유지 (보수적).
          → 보상 제어 판정을 Unverifiable → Partial로 재분류.
        INCONCLUSIVE: |
          네트워크/환경 문제로 판정 불가.
          → Unverifiable 유지, 보고서에 사유 기록.
      결과_기록: |
        VA Finding 원본의 Compensating_Controls 레코드를 업데이트:
        - coverage: Unverifiable → Effective_Complete|Effective_Narrow/Partial/Ineffective
        - verification_target: PENTEST → PENTEST_VERIFIED
        - live_evidence: "[curl 명령 + 응답 기록]"

  경로_선택_기준: |
    AI가 각 Finding의 유형을 판단하여 적절한 경로를 자율 선택한다.
    하나의 Finding이 여러 경로에 해당하면 모두 실행한다.
    Route_F는 offsec-lead로부터 Pending_Verification 목록을 수신한 경우에만 실행한다.

  Sweep_Finding_주입: |
    Phase 6.0 Sweep에서 생성된 신규 Finding 후보(F-S{NNN})도
    기존 Finding과 동일한 경로 선택 기준으로 Route A~F에 배정한다.
    - Auth Gate FAIL → Route_B (인증 우회)
    - Method Probe FAIL → Route_B (인증 우회) 또는 Route_D (비즈니스 로직)
    - Hidden EP FAIL → Route_C (정보 노출)
    - CORS FAIL → Route_B (인증 우회, credential 포함 시)
    Sweep Finding은 shallow 테스트 결과이므로 Route에서 심층 검증 후
    최종 판정(CONFIRMED/BLOCKED)을 내린다. Sweep FAIL만으로 CONFIRMED 판정 금지.

  Control_Group_사용_조건: |
    Control Group Observation은 대상 시스템에 자율 상태 변화가
    존재하는 경우에만 사용한다. 인증 키 미보유라는 이유만으로
    Control Group을 기본 대안으로 사용하지 않는다.
    인증 키 미보유 + 자율 변화 없는 시스템 → 무인증 요청의
    응답 분석과 Failure Injection만으로 판정한다.

  결과_기록_형식: |
    각 Finding별 검증 결과를 구조화하여 기록:
    ```
    ┌────────────────────────────────────────────────────────────┐
    │ LIVE VERIFICATION RESULT                                   │
    ├──────────────┬─────────────────────────────────────────────┤
    │ Finding      │ F-XXX                                       │
    │ 검증 경로    │ Route_A / B / C / D / E / F                 │
    │ 적용 기법    │ [사용한 기법 목록]                             │
    │ State Delta  │ 있음 / 없음                                  │
    │ 최종 판정    │ CONFIRMED / BLIND_ACCEPT / BLOCKED / ...     │
    │ 심각도 조정   │ 변경 없음 / 변경 사유                         │
    └──────────────┴─────────────────────────────────────────────┘
    ```
```

### 안전 원칙

```yaml
안전:
  - "프로덕션 URL 감지 시 경고 + 읽기 전용 검증만"
  - "파괴적 작업(DELETE, 자금 이동) POC는 dry-run만"
  - "Rate Limit 테스트는 최대 30회로 제한"
  - "검증 결과에 실제 curl 명령 + 응답을 증거로 기록"
  프로덕션_감지: "URL에 staging/stg/dev/test가 없는 경우"
```

### curl 템플릿

```yaml
curl_템플릿:
  보안_헤더_확인: |
    curl -s -I -X HEAD "$BASE_URL/" | grep -i -E \
      "content-security-policy|x-frame-options|strict-transport"

  무인증_접근: |
    curl -s -w "\nHTTP: %{http_code}" -X POST "$BASE_URL/api/{endpoint}" \
      -H "Content-Type: application/json" -d '{payload}'

  인증_후_비인가: |
    curl -s -w "\nHTTP: %{http_code}" -X POST "$BASE_URL/api/{endpoint}" \
      -H "Content-Type: application/json" \
      -H "Cookie: {cookie_name}={session_json}" -d '{payload}'

  rate_limit: |
    for i in $(seq 1 30); do
      HTTP=$(curl -s -o /dev/null -w "%{http_code}" ...)
      [ "$HTTP" = "429" ] && BLOCKED=$((BLOCKED+1))
    done
```

### 사용자 인터랙션

#### Phase 6 진입 시: 테스트 컨텍스트 수집

```yaml
Test_Context_Collection:
  목적: |
    Phase 6 라이브 검증 시작 전에 필요한 정보를 구조화하여 수집한다.
    코드 분석(Phase 1~5)에서 도출된 Finding 유형에 따라
    필요한 정보 항목이 달라진다.

  수집_시점: "Phase 6 진입 직전, Finding 목록 확정 후"

  기본_정보_요청:
    설명: |
      모든 라이브 검증에 공통으로 필요한 정보를 먼저 요청한다.
      사용자에게 아래 양식을 제시하고 입력을 받는다.
    양식: |
      ┌─────────────────────────────────────────────────┐
      │ CH015 Pentest — 라이브 검증 준비                    │
      ├─────────────────────────────────────────────────┤
      │                                                 │
      │ 1. 대상 URL: _______________                     │
      │    (staging/dev 환경 권장)                        │
      │                                                 │
      │ 2. 환경 타입: [ ] staging  [ ] dev  [ ] prod     │
      │    (prod 선택 시 읽기 전용 검증만 수행)             │
      │                                                 │
      │ 3. 인증 토큰 (일반 사용자):                        │
      │    Bearer: _______________                       │
      │    또는 Cookie: _______________                   │
      │                                                 │
      │ 4. (선택) 관리자 토큰:                             │
      │    Bearer: _______________                       │
      │                                                 │
      │ → 미제공 항목은 해당 검증을 건너뜁니다.              │
      │ → 추가 정보가 필요하면 검증 중 별도 요청합니다.       │
      └─────────────────────────────────────────────────┘

  Finding_기반_추가_요청:
    설명: |
      코드 분석에서 도출된 Finding 유형에 따라 추가 정보가 필요한 경우,
      기본 정보와 함께 또는 직후에 요청한다.
    분류:
      IDOR_테스트:
        조건: "AUTH-004(IDOR) 또는 인가 관련 Finding 존재"
        추가_요청: |
          IDOR 검증을 위해 두 번째 계정이 필요합니다:
          - 사용자 B 토큰: _______________
          - 사용자 A의 리소스 ID (예: agent_id): _______________
          - 사용자 B의 리소스 ID: _______________
      비즈니스_로직:
        조건: "BIZ-001~006 또는 비즈니스 플로우 관련 Finding 존재"
        추가_요청: |
          비즈니스 로직 검증을 위한 정보:
          - 테스트 가능한 리소스 ID: _______________
          - 현재 리소스 상태 (활성/비활성): _______________
      외부_API:
        조건: "외부 API 키가 필요한 Finding 존재"
        추가_요청: |
          외부 서비스 API Key:
          - 서비스명: _______________
          - API Key: _______________
      관리자_기능:
        조건: "AUTH-003(관리자 접근) 관련 Finding 존재"
        추가_요청: |
          관리자 기능 검증을 위해:
          - 관리자 토큰: _______________ (기본 정보에서 미제공 시)
          - 관리자 엔드포인트 prefix (예: /admin, /api/admin): _______________

  미제공_처리:
    원칙: "미제공 항목은 해당 Finding의 검증을 건너뛰고 NOT_TESTED로 기록"
    순서:
      1: "제공된 정보로 검증 가능한 Finding부터 먼저 실행"
      2: "추가 정보가 필요한 Finding 목록을 정리하여 사용자에게 안내"
      3: "사용자가 추가 정보 제공 시 나머지 검증 재개"
```

#### 파이프라인 중간 요청 프로토콜

```yaml
Mid_Pipeline_Interaction:
  목적: |
    라이브 검증 진행 중 추가 정보가 필요하거나,
    이전 단계 결과에 따라 새로운 정보가 필요한 경우
    사용자에게 단계적으로 요청한다.

  요청_트리거:
    토큰_만료:
      감지: "401 Unauthorized 응답이 이전에 성공했던 요청에서 발생"
      메시지: |
        ⚠️ 세션 토큰이 만료되었습니다.
        브라우저에서 새 토큰을 복사해주세요.
        현재까지 검증 완료: {completed_count}/{total_count}건
      동작: "새 토큰 수신 후 실패한 요청부터 재개"

    추가_계정_필요:
      감지: "IDOR 테스트 시 두 번째 계정 미제공 상태"
      메시지: |
        IDOR 검증(F-{id})을 위해 두 번째 계정이 필요합니다.
        - 사용자 B의 인증 토큰: _______________
        또는 이 Finding은 건너뛰시겠습니까? [건너뛰기/토큰 제공]
      동작: "건너뛰기 시 NOT_TESTED, 토큰 제공 시 검증 계속"

    리소스_ID_필요:
      감지: "특정 리소스 대상 검증 시 유효한 ID 미확보"
      메시지: |
        F-{id} 검증을 위해 테스트 가능한 리소스 ID가 필요합니다.
        - 리소스 타입: {resource_type}
        - 예시: {example_id_format}
        ID: _______________
      동작: "ID 수신 후 해당 Finding 검증 실행"

    예상치_못한_응답:
      감지: "예상과 다른 응답 구조 (엔드포인트 변경, API 버전 차이 등)"
      메시지: |
        F-{id} 검증 중 예상과 다른 응답을 받았습니다.
        요청: {request_summary}
        응답: {response_summary}
        이 엔드포인트가 맞습니까? 또는 올바른 경로를 알려주세요.
      동작: "사용자 확인 후 재시도 또는 경로 변경"

  진행_상태_보고:
    타이밍: "5건 이상 Finding 검증 시, 매 5건마다 중간 보고"
    형식: |
      ┌─────────────────────────────────────────────┐
      │ 라이브 검증 진행 상황                           │
      ├─────────────────────────────────────────────┤
      │ 완료: {done}/{total}                         │
      │ CONFIRMED: {confirmed}건                     │
      │ BLOCKED: {blocked}건                         │
      │ NOT_TESTED: {not_tested}건                   │
      │ 남은 항목 중 추가 정보 필요: {needs_info}건     │
      └─────────────────────────────────────────────┘

  검증_완료_후:
    동작: |
      모든 Finding 검증 완료 후, NOT_TESTED 항목이 있으면
      사용자에게 추가 정보 제공 의사를 확인한다.
    메시지: |
      라이브 검증이 완료되었습니다.
      - 검증 완료: {tested}건 (CONFIRMED: {c}, BLOCKED: {b})
      - 미검증: {not_tested}건 (정보 부족)

      미검증 항목에 대해 추가 정보를 제공하시겠습니까?
      {미검증 항목 목록 + 각각 필요한 정보}
```

---

## Phase 5R: 규제 영향 참조 (Regulatory Impact Reference)

```yaml
Module: "../va/regulatory.md"

Trigger: |
  Phase 1~5에서 발견된 Finding 중 규제 관련성이 있는 것이 1건 이상인 경우에만 실행.
  규제 관련 Finding이 0건이면 생략한다.

Scope: |
  가상자산, 금융, 개인정보 등 규제 민감 도메인에서 발견된 취약점을
  국내외 법률·규제 조항에 매핑하여 참고 정보로 보고서 말미에 첨부한다.
  법률 자문이 아니며, 법무팀 에스컬레이션 근거를 제공한다.
  상세 프로토콜, 규제 카탈로그, 출력 형식은 모듈 파일 참조.

Key_Principles:
  - "법률명 + 조항 번호를 반드시 명시 (모호한 언급 금지)"
  - "적용 관할(🇰🇷/🇪🇺/🇺🇸/🌐)을 명시"
  - "위반 단정 금지 — '저촉 가능성 있으므로 법무 검토 권장'으로 기술"
  - "기술적 심각도를 규제 이유로 변경하지 않음"
```

---

## Root Cause Classification (근본 원인 분류)

```yaml
Root_Cause_Types:
  ARCHITECTURE:
    description: "시스템 설계 자체의 문제 — 코드 변경만으로 해결 불가"

  CONFIGURATION:
    description: "기능은 지원되나 설정 누락 — 설정 추가로 해결"

  CODE:
    description: "로직 오류 또는 검증 누락 — 코드 수정으로 해결"

  PROCESS:
    description: "개발 프로세스/가이드라인 부재로 반복 발생하는 이슈"
```

## Finding Structure (6-step 영향도 분석)

모든 발견 사항은 아래 6-step 구조를 따릅니다.
**모든 Finding은 마크다운으로 전개해야 하며, 테이블 요약으로 대체 금지.**

> **ID 명명 규칙**: `knowledge-base/conventions/finding-id-naming.md` 참조 (F-/F-S/CAS- 통합 규칙)

```yaml
Finding_Structure:
  F-XXX: "[이슈 이름]"

  Metadata:
    Architecture_Dimension: "A1~A8 / M9 / M10"
    Severity: "CRITICAL / HIGH / MEDIUM / LOW"
    Preconditions: |
      악용에 필요한 전제조건을 열거한다. 없으면 "None".
      예: "MITM 위치 확보", "개발자가 위험 설정 활성화",
          "사용자가 악성 링크 클릭", "물리적 기기 접근" 등.
      심각도는 전제조건을 포함하여 종합적으로 판단한다.
      (기계적 심각도 조정 금지 — 영향 범위와 전제조건 난이도를 함께 고려)
    Location: "파일, 함수, 설정"
    Root_Cause: "ARCHITECTURE / CONFIGURATION / CODE / PROCESS"
    Reference:
      CWE: "CWE-NNN (필수 — 가장 정확한 CWE ID. 복수 해당 시 쉼표 구분)"
      OWASP_Top10: "A01~A10 (필수 — 해당 없으면 'N/A')"
      OWASP_API_Top10: "API1~API10 (API 도메인 활성 시 필수, 그 외 선택)"
      Note: "CWE/OWASP는 분석의 조직 원리가 아닌 보고서 완전성을 위한 필수 매핑"

  Structural_Issue_Description: "구조적 원인 설명"
  Evidence: |
    코드 참조 (file:line). VA Finding Structure의 Evidence 기준을 동일하게 적용:
    판단 기준(위험/안전 동일 증거 기준), 도달 가능성(Reachability),
    증거 분류(Observed/Unverified)를 모두 준수한다.

  Fix_Recommendation_and_Impact_Analysis:
    1_Change_Target: "수정 대상과 방향"
    2_Reference_Tracing: "호출/참조 추적"
    3_Impact_Scope: "직접/간접 영향"
    4_Side_Effect_Risks: "부작용 위험"
    5_Co_Requisite_Changes: "동시 수정 항목"
    6_Post_Fix_Verification: "검증 항목"
```