# task-2985 — InsuRo P0 보안 2건: 본인확인 우회 · OAuth 동의 게이트 우회

**레벨**: Lv.2 (보안) · **팀**: dev3-team (다그다) · **level=security** · **회장 승인 완료** (2026-08-20)

## 배경
개인정보처리방침을 게시해도 이 두 건은 해소되지 않는다. 코드 결함이다.
두 건 모두 base `60c3871b` 부터 존재하던 기존 결함으로, task-2983 범위 밖으로 미뤄둔 것이다.

## P0-1 — 명함 토큰 본인확인 자력 통과 + 타인 레코드 무단 수정

**위치**: `src/pages/CustomerChat.tsx` (기존 확인 지점 122-126 부근. 줄번호는 바뀌었을 수 있으니 **직접 확인**할 것)

**정확한 성립 조건** — 봇 보고가 과장했던 부분이니 그대로 믿지 말고 코드로 재확인하라:
- 현재 로직은 이름 + 전화번호 **양쪽 일치**를 요구한다. 따라서 "이름만 추측하면 뚫린다"는 **무조건 성립하지 않는다.**
- 실제 성립 조건은 **대상 고객의 전화번호가 비어 있을 때**다. 이때 방문자가 입력한 값으로 빈 칸이 덮어써지면서 본인확인을 스스로 통과한다.
- 다만 **익명 사용자가 타인 고객 레코드를 무단 수정한다**는 사실 자체는 조건 없이 성립한다. 이쪽이 더 근본 문제다.

**요구사항**:
1. 본인확인 과정에서 **기존 고객 레코드를 쓰기(덮어쓰기)하지 않는다.** 확인은 읽기 전용이어야 한다.
2. 전화번호가 비어 있는 고객은 **자동 통과시키지 말고 명시적으로 실패 처리**한다(fail-closed). 빈 값을 "일치"로 취급하지 않는다.
3. 실패 시 어떤 필드가 틀렸는지 노출하지 않는다(열거 공격 방지).

## P0-2 — Google OAuth 최초 로그인 동의 게이트 우회

**증상**: Google OAuth 최초 로그인 경로에서 개인정보 수집·이용 동의 게이트를 거치지 않고 진입한다.

**요구사항**:
1. 최초 로그인 사용자는 동의 완료 전까지 서비스 본 화면에 진입할 수 없어야 한다.
2. 동의 여부는 **서버/DB 상태**로 판정한다. 클라이언트 상태만으로 판정하지 말 것(우회 가능).
3. 기존 가입자에게는 영향이 없어야 한다.

먼저 **실제 코드 경로를 확인**하고, 위 증상이 재현되는지 직접 검증한 뒤 착수하라. 재현되지 않으면 그 사실을 근거와 함께 보고하고 멈춘다.

## 범위 (엄수)
**수정 금지**:
- `src/components/PwaInstallPrompt.tsx` 와 `src/App.tsx` — **task-2984 가 동시에 작업 중**이다.
- 배포 실행 금지. `wrangler pages deploy` 는 task-2984 담당이다.

수정이 위 금지 파일로 번져야만 해결된다고 판단되면, **작업을 멈추고 ANU 에게 보고**하라. 임의로 범위를 넓히지 말 것.

## 선행 조건
로컬이 뒤처져 있다. `origin/main = d8ee3e6` (task-2983 PR#235) 기준으로 `git pull --ff-only` 후 시작한다.

## 검증
1. `npm run build` EXIT=0
2. `npx vitest run` — 1226 passed 유지. 감소 시 중단·보고.
3. **결함 재현 테스트를 먼저 작성**하라(수정 전에 FAIL 하는 테스트). 수정 후 PASS 로 전환되는 것을 증거로 남긴다. 이게 없으면 "고쳤다"의 근거가 없다.
4. 우회 시도 프로브: 전화번호 빈 고객 / 타인 이름 추측 / OAuth 최초 로그인 직후 본 화면 직접 접근 — 최소 3종이 전부 차단되는 것을 실증한다.
5. 실브라우저로 정상 사용자 흐름이 깨지지 않았음을 확인한다.

## 완료 조건
빌드 0 · 회귀 유지 · 재현 테스트 FAIL→PASS 전환 증거 · 우회 프로브 3종 차단 실증 · 정상 흐름 무손상

## allowed_resources (본 task의 capability)

```yaml
allowed_resources:
  paths:
    - "src/pages/CustomerChat.tsx"
    - "src/integrations/**"
    - "src/hooks/**"
    - "src/lib/**"
    - "tests/**"
    - "e2e/**"
    - "supabase/**"
    - "memory/reports/task-2985.md"
  forbidden_paths:
    - "src/components/PwaInstallPrompt.tsx"
    - "src/App.tsx"
    - ".github/**"
    - "memory/events/*.cron-*"
  commands:
    - "npm run build"
    - "npx vitest run"
    - "npx playwright test"
  merge_policy: "tiered"
  ttl_hours: 48
```

## 보고
**PR 생성까지가 범위다. 머지는 ANU 가 한다.** 완료 시 `memory/reports/task-2985.md` 작성 후 ANU 콜백.
콜백 프롬프트는 **UTF-8 3900 bytes 이하**, 봉투에는 경로·PR 번호·한 줄 요약만 담는다.
시크릿 스캔은 `.py`/`.ts` 소스뿐 아니라 **컴파일·빌드 산출물(dist 등)까지** 훑는다.

## goal_assertions (auto-generated)
- `npm run build`
- `npx vitest run`
