# task-1802 완료 보고서 — FloatingTermDetection 보안 취약점 수정 + UI 개선

**팀**: dev3-team (다그다)
**검증 레벨**: security
**일시**: 2026-04-14

---

## SCQA

**S**: InsuWiki의 FloatingTermDetection 컴포넌트(ManualTermInput)가 문서 검색 시 Firestore `searchKeywords` 필드만으로 전체 문서를 쿼리하고 있다.

**C**: 이 쿼리는 `visibility`/`authorId` 필터가 없어 다른 사용자의 private 문서 제목이 검색 결과에 노출되는 보안 취약점이 존재한다. 또한 검색 드롭다운 최대 높이가 160px로 고정되어 결과가 잘리는 UX 문제도 있다.

**Q**: private 문서 노출을 차단하고, 드롭다운 UX를 개선할 수 있는가?

**A**: BacklinksPanel.tsx의 `and(or())` 필터링 패턴을 적용하여 `visibility == 'public' OR 'shared' OR authorId == currentUser.uid` 조건으로 검색 범위를 제한했다. 추가로 미인증 사용자 가드, 문서 생성 시 인증 검증을 추가했다. vitest 9/9 통과, 마아트/로키 검증 완료.

---

## 수정 내용

### 1. 보안 취약점 수정 (CRITICAL)
- `handleSearch`: `and(or(visibility=='public', visibility=='shared', authorId==uid), searchKeywords)` 복합 쿼리 적용
- `handleSearch`: `currentUser` null 가드 추가 (미인증 시 검색 차단)
- `handleCreateAndConnect`: `currentUser` null 가드 추가 (미인증 시 문서 생성 차단)
- `authorId: 'system'` fallback 제거 → non-null `currentUser.uid` 직접 사용

### 2. UI 개선
- 드롭다운 `max-h-40` (160px 고정) → `Math.min(results.length * 40, 400)px` 동적 높이
- 1~10개 항목: 항목 수에 따라 높이 동적 조절
- 10개 초과: 400px 고정 + 스크롤

### 3. 테스트 업데이트
- firebase/firestore 모킹에 `and`/`or` 함수 추가
- TC-2에 보안 필터 검증 assertion 5개 추가 (visibility public/shared, authorId, mockOr, mockAnd)

---

## Firestore Rules 검증

`firestore.rules` documents 컬렉션 read 규칙 (line 85-91):
- `isAuthenticated() && isMemberOrAdmin()` + `isPublic() || isAuthor()` 조건
- `isPublic()`: `visibility == 'public' || 'shared' || 필드 없음`
- 서버 측 규칙이 클라이언트 필터링을 보완하는 2중 방어 구조 확인
- 규칙 자체에 수정 필요 없음

---

## 산출물 파일

- `/home/jay/projects/insuwiki/nextapp/src/components/FloatingTermDetection.tsx`
- `/home/jay/projects/insuwiki/nextapp/src/components/__tests__/FloatingTermDetection.test.tsx`

---

## 테스트 결과

- vitest: **9/9 passed** (3.65s)
- TC-1: 수동 입력 UI 렌더링 (2건 PASS)
- TC-2: 검색 기능 + 보안 필터 검증 (1건 PASS)
- TC-3: 자동완성 드롭다운 (1건 PASS)
- TC-4: 연결 생성 (1건 PASS)
- TC-5: 연결 성공 토스트 (1건 PASS)
- TC-6: AI 추천 0건 수동 입력 (1건 PASS)
- TC-7: 매칭 없을 때 신규 생성 옵션 (1건 PASS)
- TC-8: 신규 용어 생성 및 연결 (1건 PASS)

---

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **미인증 사용자 쿼리 실행 가능** — handleSearch에 currentUser null 가드 추가 (line 35-39)
2. **visibility 'shared' 문서 검색 누락** — or 조건에 `where('visibility', '==', 'shared')` 추가 (line 50)
3. **handleCreateAndConnect 인증 미검증** — currentUser null 가드 + toast.error 추가, 'system' fallback 제거 (line 112-116, 129-130)

### 범위 외 미해결 (2건)
1. **ai_suggestions 서브컬렉션 소유자 검증 미흡** — 범위 외 사유: Firestore Rules 수정은 인프라/보안팀 소관. 별도 task 필요.
2. **BacklinksPanel 내부 visibility 값 혼용 (public vs shared)** — 범위 외 사유: 기존 코드 리팩토링은 별도 task 필요. 현재 동작에 보안 문제 없음.

---

## 마아트 독립 검증 결과

- 1-A import 추가: PASS
- 1-B 보안 쿼리 구조: PASS
- 1-C 비인증 사용자 미처리: FAIL → **수정 완료**
- 1-D 동적 maxHeight: PASS
- 2-A visibility 'shared' 누락: FAIL → **수정 완료**
- 3-A and/or 모킹: PASS
- 3-B TC-2 보안 assertion: PASS
- 3-C TC 번호 순서 불일치: FAIL (기존 코드, 범위 외)
- 4-A Rules vs 쿼리 갭: FAIL → **수정 완료** (shared 추가)

## 로키 보안 감사 결과

- FINDING-01 private 문서 노출 차단: SECURE
- FINDING-02 미인증 사용자 쿼리: WARN → **수정 완료**
- FINDING-03 shared/레거시 문서 불일치: WARN → **shared 추가로 수정 완료**
- FINDING-04 미인증 사용자 문서 생성: VULNERABLE (HIGH) → **수정 완료**
- FINDING-05 ai_suggestions 소유자 검증: WARN (범위 외)

---

## 머지 판단

- **머지 필요**: Yes → **머지 완료** (Fast-forward)
- **브랜치**: task/task-1802-dev3
- **워크트리 경로**: /home/jay/projects/insuwiki/.worktrees/task-1802-dev3
- **머지 의견**: 보안 취약점 수정 + QC 이슈 3건 모두 해결 완료. vitest 9/9 통과. 충돌 없음 (Fast-forward).

---

## QC 자동 검증 결과

```json
{
  "overall": "PASS (1 WARN)",
  "file_check": "PASS",
  "data_integrity": "PASS",
  "test_runner": "SKIP (관련 테스트 0개 — 프로젝트 디렉토리 외부)",
  "tdd_check": "WARN (프로젝트 파일이 /home/jay/projects/insuwiki/에 위치하여 workspace audit-trail 미추적. 실제 테스트는 vitest 9/9 통과)",
  "critical_gap": "PASS (CRITICAL 1건 해결됨)",
  "spec_compliance": "PASS",
  "duplicate_check": "PASS (최대 유사도 7.8%)"
}
```

---

## 모델 사용 기록

- 브리짓(Brigid) / 보안 수정 + UI 개선 코딩 / sonnet / -
- 브리짓(Brigid) / 테스트 모킹 수정 / sonnet / -
- 브리짓(Brigid) / QC 이슈 수정 (인증 가드, shared) / sonnet / -
- 마아트(Maat) / 독립 검증 / sonnet / -
- 로키(Loki) / 보안 감사 / sonnet / -

## 세션 통계
- 총 도구 호출: 4회

### 수정 파일 목록
- /home/jay/workspace/memory/reports/task-1802.md: 2회 (Edit, Write)
- bash_cmd: 2회 (Bash)

### 도구 사용 현황
- Bash: 2회
- Edit: 1회
- Write: 1회

