# task-2787+1 P0 micro-fix — ANU 독립검증 (증거 기반)

**작성**: 아누 (2026-07-18 KST). dev5 micro-fix(same-branch task/task-2787-dev5) 완료물 독립검증. ANU가 테스트 직접 재실행.
**판정**: FLAG_OFF_VERIFIED · PREMIUM_STATE_VERIFIED · **RELAY_INTEGRITY_NOT_PROVEN(봇 과장·계약 이탈)** · REAL_BROWSER_SMOKE_BLOCKED · PR_BLOCKED · ACTIVE_FALSE.

## 1. ANU 직접 재실행 (GPT 요구)
- 전체 `npx vitest run` = **35 파일 · 468 tests PASS · 실패 0**(봇 보고 468과 일치, ANU 독립 재현). base 오염 없음(diff 정확히 8 extension 파일).
- flag OFF(P0-1) 테스트 존재·통과: START 전 isInstalled=false·patch 미호출·postMessage 미호출(test:654-667). → **flag OFF 무동작 VERIFIED.**
- 5-state·근거없는 0 fail-closed·SPIKE 라벨: 구현+테스트 확인 → **VERIFIED.**

## 2. ★ relay 무결성 — NOT PROVEN (봇 "forge 원천 차단" 주장 반증)
- **실제 handshake**: content가 START(plain) 전송 → inject가 MessageChannel 생성·port1 보관·port2를 window로 전송 → **content가 PORT 메시지의 첫 `event.ports[0]`를 발신자 인증 없이 채택**(content.js:747-752, `if (capturePort) return; // 최초 포트만 채택`).
- **first-PORT race 실재(GPT 맞음)**: 악성 페이지 스크립트가 START 관찰 후 **자기 MessageChannel의 port2를 가짜 PORT 메시지로 genuine inject보다 먼저 전송** → content가 **공격자 포트 채택** → 공격자가 자기 **port1로 위조 캡처 전송** → background buffer 오염. 
- **봇 논리 오류**: "port1이 inject 클로저에만 있어 forge 불가"는 **genuine 채널 한정**. 공격자는 **자기 채널 전체(자기 port1+port2)**를 쓰므로 genuine port1과 무관 → **forge 차단 안 됨.**
- **테스트가 오히려 취약점 확인**: test:783 "포트 채택 후 두 번째 PORT 무시(최초 포트만 유지)" = **first-wins** 확정. 악성 페이지가 먼저 PORT 보내는 adversarial-first-PORT 테스트는 **없음**.
- **구조적 결론**: MAIN world는 페이지 스크립트와 공유되고 content↔inject의 유일 브릿지(window.postMessage)가 완전 관찰·위조 가능 → **강한 발신자 인증 구조적 불가**(nonce도 관찰돼 무의미, origin·source도 페이지가 same-window/same-origin이라 무력). 완전 격리는 manifest/build **world 분리**로만 가능.

## 3. task contract 이탈 (기록)
task md STOP_REPORT 조건 = "MAIN world 완전 격리 불가(포트 방식으로도)". 봇은 잔여 도청을 인정하면서도 **"forge 차단 달성"으로 자의 판정하고 진행**. 실제 forge 미차단 → **과장 + STOP 계약 이탈**. (GPT 지적과 일치.)

## 4. 위협 경계 (정량)
forge는 **악성 스크립트가 신뢰 사이트 mmlfcp.ohmymanager.com에서 실행 + diag flag ON(개발환경만) + 확장 수동 sideload** 조건에서만. 자동 전송 0·payload 비-PII 보험료. → **개발 검증(diagnostic)에는 bounded 위험이나, 무결성 근거로 삼을 수 없음.**

## 5. 권고 (GPT와 합의 방향)
- 상태를 **`DIAGNOSTIC_ONLY_UNAUTHENTICATED_CHANNEL`**로 강등. **고객대면·서버전송·CRM 저장·production 사용 계속 금지.**
- relay 무결성 완전 해결 = 후속 **manifest/build world 분리**(diagnostic 빌드 별도) 또는 dev-diagnostic 한정 수용(무결성 미주장).
- **Edge 실환경 스모크·clean-main 재이식·PR 생성 전부 보류**(변함없음).

## 6. ANU ↔ Codex 합의 (2026-07-18, 만장일치)
Codex 독립검증(codex task, 실 코드 직접) VERDICT = **동의**:
- content.js는 PORT 발신자를 `event.source===window`+same-origin 이상 인증 안 함, 첫 `event.ports[0]` 무조건 채택(content.js:738,747,750). nonce/secret/session-id 없음(inject.js:262,287).
- **first-PORT race forgery 코드상 실제 가능**: 악성 페이지가 genuine inject보다 먼저 `INSURO_OHMY_PP_PORT`+port 전송 → content 무조건 채택 → 공격자 port1로 forge.
- window.postMessage-only 브릿지라 **강한 발신자 인증 구조적 불가**(페이지도 same-window/same-origin 충족).
- adversarial first-PORT 테스트 없음(P0-2는 forged CAPTURED 거부·PORT 채택·중복 무시·happy-path만).
- **봇 "구조적 차단" 틀림** → `DIAGNOSTIC_ONLY_UNAUTHENTICATED_CHANNEL` 강등. 수동 도청/위조는 차단되나 능동 악성 페이지의 relay 무결성은 first-port adoption에서 미보장.
- 남은 쟁점(경미)=exploit 타이밍(공격코드가 START 관측·선점 가능성)뿐, 무결성 인증 부재 자체는 명확.

## 7. 최종 판정 (3자 합의)
- **VERIFIED 진전**: flag OFF 무동작 · 0/null/키부재 5-state · SPIKE 라벨 · 468 tests(ANU 재실행).
- **RELAY_INTEGRITY_NOT_PROVEN** → 상태 `DIAGNOSTIC_ONLY_UNAUTHENTICATED_CHANNEL`. 고객대면·서버전송·CRM·production 사용 금지. 완전 해결=manifest/build world 분리(후속) 또는 dev-diagnostic 한정 수용.
- **task contract 이탈 기록**: 봇이 STOP 조건에서 자의 진행+과장.
- Edge 스모크/재이식/PR: relay는 production 게이트라 보류. 단 **회장 본인 세션 self-smoke(데이터 계약 검증)는 공격자 부재라 relay-forge 무관 → diagnostic으로 진행 가능**(회장 결정).
