마크다운 링크 protocol 필터 회귀 테스트 - #215
Merged
Merged
Conversation
기존 XSS 테스트(raw HTML/script)는 react-markdown 이 raw HTML 을 escape 하므로 rehype-sanitize 가 없어도 통과한다 — 즉 sanitize 플러그인이 실제로 붙어 있는지는 검증하지 못한다. 링크 protocol 필터링은 오직 rehype-sanitize 만 막아주므로 그 경로를 덮는다. javascript: / 대소문자 우회 / data:text/html 세 가지에서 href 가 제거되는지, 그리고 정상 https 링크는 살아남는지(과잉 차단 아님) 확인한다. rehype-sanitize 를 빼면 앞 3개만 실패하는 것을 확인했다. 렌더 대상(분석 문서 마크다운·answerRewrite)이 사용자 이력서·답변에서 파생되므로, 스키마를 커스터마이즈하거나 플러그인을 빼는 변경이 조용히 통과하면 안 된다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
배경
#213 의
MarkdownContent를 리뷰하다 발견한 테스트 공백이다. 렌더러 자체는 안전하다 — raw HTML 미허용 +rehype-sanitize. 문제는 그 방어가 테스트로 고정돼 있지 않다는 점이다.기존 테스트:
이 케이스는
rehype-sanitize를 빼도 통과한다. react-markdown 이 기본적으로 raw HTML 을 escape 하기 때문이다. 즉 sanitize 플러그인이 실제로 붙어 동작하는지는 아무것도 검증하지 못하고 있었다.링크 protocol 필터링은 오직 rehype-sanitize 만 막아준다 — 여기가 그 플러그인의 실질 담당 구역이다.
무엇
마지막 케이스는 과잉 차단 회귀를 막는다 — 필터를 조이다 정상 링크까지 죽이면 AI 리포트의 참고 링크가 전부 먹통이 된다.
실효성 확인
rehype-sanitize를 제거하고 돌리면 앞 3개만 실패하고 정상 링크 케이스는 통과한다. 테스트가 의도한 지점을 정확히 겨냥하고 있다는 뜻이다.왜 지금
Markdown의 렌더 대상이 사용자 입력에서 파생된다:DocumentListAnswerCoachingAccordionanswerRewrite— 사용자 답변을 AI 가 다시 쓴 것FeedbackAiReport/ReviewBlockAI 를 거치긴 하지만 사용자 텍스트가 흘러 들어가는 경로다. 지금은 안전한데, 나중에 sanitize 스키마를 커스터마이즈하거나(테이블 정렬·클래스 허용 등 자연스러운 요구다) 플러그인을 걷어내는 변경이 조용히 통과하면 안 된다.
확인했고 문제없던 것 (리뷰 결과)
MarkdownContent에rehype-raw없음, 링크에target="_blank" rel="noreferrer"✅Markdown사용처 5곳 모두 AI 생성 필드 — 사용자 원문 직접 렌더 없음 ✅feedback_report.py)에 사용자 답변 원문 미포함, 질문은 개행 정규화 후 헤딩 삽입 ✅GET /feedback/report)는ownedFeedback소유권 검증, 키는 DB 출처라 경로 주입 없음 ✅