# findings — `00-protocol`

기록 형식은 `README.md` 를 따른다. 판단·수정 제안은 적지 않는다.

동결 SHA (행 번호는 이 SHA 기준):

| 저장소 | SHA |
|---|---|
| `insuniverse-server` | `4d798f55f021d93c889725e50f18cbce20272fd1` |

## `GET /admin/menu/all` 무인증 노출

`.claude/meta/06-access-model-findings.md` §2-1 에서 이관했다. 원본은 그 자리의 실측 기록으로 남고, 이 파일이 정본 위치다.

### 발견 일시

2026-08-05

### 관찰 사실

`GET https://s-api.insuniverse.com/admin/menu/all` 이 **쿠키 없이 HTTP 200** 을 반환하며, 본문은 전체 메뉴 트리 JSON 이다 — `mnuId` · `mnuName` · `mnuCode` · `mnuUrl` · `mnuDepth` · `mnuParentId` 전부.

대조군 `GET https://s-api.insuniverse.com/admin/authority` 는 같은 조건에서 HTTP 401 이다. 전역 인증 자체는 동작하며, 리버스 프록시 계층도 이 엔드포인트를 막지 않는다.

prod 는 확인하지 않았다 — 도메인이 제공되지 않았다. **동일 코드가 배포돼 있다면 prod 도 같을 것으로 보이나 미검증이다.**

### 재현 절차

- 도구: Playwright
- 환경: stg 실환경 (사용자 요청 · 도메인 제공, 2026-08-05)
- 절차: 쿠키 없는 GET 2건

| 요청 | 쿠키 | 결과 |
|---|---|---|
| `GET https://s-api.insuniverse.com/admin/menu/all` | 없음 | HTTP 200 — 전체 메뉴 트리 JSON |
| `GET https://s-api.insuniverse.com/admin/authority` | 없음 | HTTP 401 (대조군) |

### 근거 앵커

`insuniverse-server` @ `4d798f55f021d93c889725e50f18cbce20272fd1`

| 파일:행 | 관찰 |
|---|---|
| `apps/api/src/modules/menu/menu.controller.ts:15` | `@Get('all')` 에 `@UseGuards` 가 없다 |
| `apps/api/src/main.ts:18-21` | `useGlobalGuards` 가 없다 — `bodyParser` · `cookieParser` 뿐 |
| `apps/api/src/app.module.ts` | provider 가 `APP_PIPE`(ClassValidatorPipe) 하나뿐이고 `APP_GUARD` 가 없다 |

### 심각도

**정보 노출.** 자격증명·개인정보는 포함되지 않는다. 노출 내용은 관리자 **메뉴 구조 전체**(이름 · 코드 · URL · 계층)이며, 관리자 화면 경로가 전수 드러나므로 공격 표면 매핑에 쓰인다.

### 상태

`사용자 통보`
