## 요약
- 확정 취약: N건 (High n / Medium n)
- 차단 확인: M건 (이스케이프·필터 정상 동작)
## 확정 취약점
### [High] 반사형 XSS — 검색 파라미터 q — /search?q=
- 유형 / 위치: 반사형 / GET /search?q=
- **① 취약한 점(What)**: 검색 파라미터 `q` 값이 JSP EL `${param.q}`로 이스케이프 없이 HTML에 출력됨.
- **② 취약한 이유(Why)**: JSP EL 표현식은 HTML 자동 이스케이프를 수행하지 않는다.
사용자가 입력한 `
```
- **④ 해결방법(Fix)**:
```jsp
<%-- Before (취약) --%>
${param.q}
<%-- After (안전) --%>
<%-- 또는: ${fn:escapeXml(param.q)}
--%>
```
- **Evidence**:
- 주입 페이로드: ``
- 반사 위치: 응답 HTML body, 이스케이프 없이 원문 반사 (attack_xss.py 반사 컨텍스트: html_body)
- 브라우저 실행: `browser_evaluate` 결과 `{"fired":"sqixss4f2a1b3c"}` 확인
- 스크린샷: `evidence/reflected_xss_search_q.png`
- 콘솔 로그: (별도 첨부)
- 참조: CWE-79, OWASP A03:2021
### [High] 저장형 XSS — 게시판 본문 — /board/view?id=123
- 유형 / 위치: 저장형 / POST /board/write → GET /board/view?id=123
- **① 취약한 점(What)**: 게시글 본문 `content` 필드가 DB에 원문 저장되고, 조회 시 `${board.content}`로 이스케이프 없이 출력됨.
- **② 취약한 이유(Why)**: 저장 단계에서 입력 필터링 없음 + 출력 단계에서 HTML 이스케이프 없음.
조회하는 **모든 사용자**의 브라우저에서 저장된 스크립트가 실행됨(피해 범위 넓음).
- **③ 뚫리는 방법(How)**: 공격자가 게시글 본문에 아래를 저장:
```html
```
다른 사용자가 글을 조회하면 세션 쿠키가 공격자 서버로 전송됨.
관리자 조회 시 관리자 권한으로 악성 동작 수행 가능(권한 상승).
- **④ 해결방법(Fix)**: 출력 이스케이프 적용. HTML 에디터 허용 시 AntiSamy/jsoup 허용 목록 필터.
```jsp
<%-- Before (취약) --%>
${board.content}
<%-- After (안전, 일반 텍스트) --%>
<%-- After (리치 텍스트 허용 시) — AntiSamy 서버 측 정화 후 출력 --%>
${board.sanitizedContent}
```
- **Evidence**:
- 주입 페이로드: `
`
- 주입 위치: POST /board/write, 파라미터 content
- 실행 확인: /board/view?id=123 조회 후 `browser_evaluate` 결과 `{"fired":"sqixssSTORED01"}` 확인
- 스크린샷: `evidence/stored_xss_board_content.png`
- 참조: CWE-79, OWASP A03:2021
## 차단 확인 (이스케이프 정상 동작)
- GET /notice?keyword= — `fn:escapeXml()` 래핑으로 마커 이스케이프됨 (안전)
```
---
## Verification (검증 체크리스트)
- [ ] scope_guard가 대상을 차단하지 않고 통과했는가 (로컬/스테이징 확인)
- [ ] attack_xss.py가 각 파라미터에 7가지 페이로드를 모두 주입했는가
- [ ] 반사형: HTTP 응답 반사 확인 **AND** Playwright `window.__xss_fired` 확인을 모두 수행했는가
- [ ] 저장형: 주입 후 **조회 페이지**를 Playwright로 열어 실행 여부를 확인했는가
- [ ] DOM XSS 후보는 Playwright MCP로 브라우저에서 직접 URL 이동 후 확인했는가
- [ ] 각 확정 취약점에 Evidence 4항목(페이로드·반사위치·실행 결과·스크린샷)이 붙어 있는가
- [ ] 스크린샷 파일이 `evidence/` 디렉토리에 저장됐는가
- [ ] 해결방법이 해당 스택(JSP/Spring/React)에 맞게 구체적으로 기술됐는가
---
## Key Concepts
| 용어 | 설명 |
|---|---|
| 반사형 XSS | URL 파라미터 등 요청 값이 즉시 응답에 출력되어 브라우저에서 실행 |
| 저장형 XSS | 악성 스크립트가 DB에 저장되어 다른 사용자 조회 시 실행 — 피해 범위 넓음 |
| DOM XSS | 서버 응답이 아닌 클라이언트 JS가 DOM을 조작할 때 발생 — HTTP 반사 검사로 불검출 |
| 고유 마커 | `sqixss<랜덤8자>` — 중복 방지용 식별자. 응답에서 미이스케이프 반사 여부 확인에 사용 |
| `window.__xss_fired` | Playwright가 브라우저 실행 확인에 사용하는 전역 변수 마커 |
| scope_guard | 운영 대상 발사를 코드 수준에서 차단하는 안전 게이트 |
| 비파괴 페이로드 | 마커 변수 설정만 수행, 데이터 변조·삭제·외부 전송 없음 |
## Tools & Systems
- `scripts/attack_xss.py` — HTTP 반사 검사 (scope_guard 내장)
- `tools/scope_guard.py` — 안전 게이트 (운영 차단)
- Playwright MCP — 브라우저 실행 확인, 증거 스크린샷 수집
- `references/payloads.md` — 컨텍스트별 페이로드 레퍼런스
- 연계 스킬: `detecting-xss-vulnerabilities` (정적 후보 도출)