docs(retro): 세션 20260630-113258 회고 교훈 3건 docs 반영

- CLAUDE.md: 정적 CSS/JS Tomcat DefaultServlet 서빙 경로 규약 추가
- security-remediation-checklist: B5 recruit-form CSRF 폴백 갭 (P0) 추가
- verification-strategies: graphify 스캔 범위 JSP/CSS/JS 미포함 교훈 추가
- report.md: ended_at 기록

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3FeMrbtxfTScjrwUukyHD
This commit is contained in:
이정수 2026-06-30 12:11:04 +09:00
parent 770d3922e2
commit 3726ce54f2
4 changed files with 25 additions and 1 deletions

View File

@ -2,7 +2,7 @@
schema_version: "2" schema_version: "2"
sid: "20260630-113258" sid: "20260630-113258"
started_at: "2026-06-30T11:32:58" started_at: "2026-06-30T11:32:58"
ended_at: ~ ended_at: "2026-06-30T12:10:51"
user_request: > user_request: >
/frontend-design:frontend-design 프론트 코드들 컴포넌트별로 매번 새로 /frontend-design:frontend-design 프론트 코드들 컴포넌트별로 매번 새로
구현하는건 없는지 유지 보수, 확장 차원에서 부족한건 없는지 검토하자 구현하는건 없는지 유지 보수, 확장 차원에서 부족한건 없는지 검토하자

View File

@ -8,6 +8,7 @@
- 화면은 `/WEB-INF/views/*.jsp`를 사용한다. - 화면은 `/WEB-INF/views/*.jsp`를 사용한다.
- DB 접근은 annotation 기반 MyBatis mapper를 사용한다. - DB 접근은 annotation 기반 MyBatis mapper를 사용한다.
- 업로드된 프로필 이미지는 `/profile/**`, 게임 WebGL asset은 `/game/{gameUuid}/**`로 제공된다. - 업로드된 프로필 이미지는 `/profile/**`, 게임 WebGL asset은 `/game/{gameUuid}/**`로 제공된다.
- 정적 CSS/JS 파일은 `src/main/webapp/css/`, `src/main/webapp/js/`에 두면 Tomcat DefaultServlet이 직접 서빙한다. `src/main/resources/static/`은 WAR에서 불필요하다.
## 작업 원칙 ## 작업 원칙

View File

@ -281,3 +281,9 @@ nullable 파라미터 타입별 캐스트:
implementation-advisor 가 여러 code-writer worker 로 파일을 분산 수정한 뒤 반환하는 완료 summary 는 worker 상태 추적 혼선으로 **실제 변경과 불일치**할 수 있다("Worker C만 완료" 보고했으나 실제 4파일 적용 등). orchestrator 는 advisor summary 를 그대로 신뢰하지 말고 `git diff --stat` / 대상 파일 grep 으로 **실변경을 교차검증**한 뒤 다음 단계로 진행한다. implementation-advisor 가 여러 code-writer worker 로 파일을 분산 수정한 뒤 반환하는 완료 summary 는 worker 상태 추적 혼선으로 **실제 변경과 불일치**할 수 있다("Worker C만 완료" 보고했으나 실제 4파일 적용 등). orchestrator 는 advisor summary 를 그대로 신뢰하지 말고 `git diff --stat` / 대상 파일 grep 으로 **실변경을 교차검증**한 뒤 다음 단계로 진행한다.
> 근거: B2·B4·FE 세션(20260629) — FE implementation-advisor 가 불완전 summary 반환, git diff 로 4파일 적용 확인 후 진행. profile 미변경은 "입력 컨트롤 없음=정상"으로 판별. > 근거: B2·B4·FE 세션(20260629) — FE implementation-advisor 가 불완전 summary 반환, git diff 로 4파일 적용 확인 후 진행. profile 미변경은 "입력 컨트롤 없음=정상"으로 판별.
### graphify 스캔 범위 — JSP/CSS/JS 정적 자산 미포함
graphify(`/graphify src/ docs/`)는 `src/main/webapp/WEB-INF/views/*.jsp`, `src/main/webapp/css/`, `src/main/webapp/js/` 등 정적 자산을 스캔 범위에 포함하지 않는다. 프론트엔드 분석 태스크에서 graphify-lookup-advisor가 miss를 반환하는 것은 예상 결과다 — research-advisor 직접 탐색으로 대체한다.
> 근거: 세션 20260630-113258 — graphify-lookup miss 즉시 확인, research-advisor로 전환해 JSP 26개 전수 탐색 성공.

View File

@ -181,3 +181,20 @@
- [ ] 업로드: `../`, 절대 경로, nested zip, 과대 zip을 거부한다. - [ ] 업로드: `../`, 절대 경로, nested zip, 과대 zip을 거부한다.
- [ ] XSS: 게임 이름, 제작자 한마디, 댓글, 검색어가 HTML로 실행되지 않는다. - [ ] XSS: 게임 이름, 제작자 한마디, 댓글, 검색어가 HTML로 실행되지 않는다.
- [ ] 권한: 게임 수정/삭제, 댓글 삭제, 프로필 변경은 소유자 또는 로그인 조건을 확인한다. - [ ] 권한: 게임 수정/삭제, 댓글 삭제, 프로필 변경은 소유자 또는 로그인 조건을 확인한다.
## B5. recruit-form.jsp CSRF 폴백 갭 (P0-보안)
근거:
- `BibimbapCsrf` 미존재(비로그인 등) 시 fetch 폴백 브랜치에서 CSRF 토큰이 헤더에 포함되지 않는다. `src/main/webapp/WEB-INF/views/recruit-form.jsp:386-394`
- hidden `_csrf` input 부재 — form submit fallback도 보호 없음.
체크리스트:
- [ ] `recruit-form.jsp``<input type="hidden" name="_csrf" value="...">` 추가한다.
- [ ] fetch 폴백 브랜치 headers에 `'X-CSRF-Token': csrfToken` 추가한다.
- [ ] 수정 후 CSRF 없는 POST가 거부되는 회귀 테스트를 추가한다.
완료 조건:
- [ ] `BibimbapCsrf` 미존재 시에도 recruit-form POST에 CSRF 토큰이 전송된다.
- [ ] 토큰 없는 요청이 403으로 거부된다.
> 발견: 세션 20260630-113258 JSP 프론트엔드 컴포넌트 검토.