flawopen.com/XSS/Markdown 렌더링
Markdown 렌더링은 XSS로부터 안전한가요?
Markdown에서 생성한 HTML은 신뢰할 수 없는 콘텐츠로 취급하세요. 문법이 허용하므로 파서가 원시 HTML을 그대로 보존할 수 있으며, Markdown 변환 자체는 출력을 정화하지 않습니다. 파서는 마크업 번역기이지 보안 경비원이 아닙니다.
신뢰 경계는 어디인가
CommonMark 명세에 따르면 태그 형태의 원시 HTML은 이스케이프 없이 렌더링됩니다. 실제 동작은 파서, 옵션, 플러그인, 호스트 프레임워크에 따라 달라집니다. 예를 들어 Marked는 생성된 HTML을 정화하지 않는다고 명시합니다. Markdown 문법만으로 입력이 안전하다고 입증할 수 없습니다. 정화기는 최종 HTML 삽입 지점을 보호해야 합니다.
안전한 렌더링 흐름
const html = marked.parse(userMarkdown); container.innerHTML = html; // 파서 출력이 정화되지 않음
import DOMPurify from "dompurify";
const html = marked.parse(userMarkdown);
container.innerHTML = DOMPurify.sanitize(html, {
USE_PROFILES: { html: true }
});
예제는 이 화면에 SVG나 MathML이 필요하지 않으므로 DOMPurify의 HTML 전용 프로필을 사용합니다. 제품에 필요한 기능만 허용하세요. 정화된 마크업을 수정하거나 삽입 전에 다른 HTML 변환 라이브러리에 전달하지 마세요. 보장이 무효화될 수 있습니다. 리치 HTML이 필요 없다면 프레임워크의 안전한 텍스트 렌더링을 사용하세요. Content Security Policy와 Trusted Types는 추가 방어이며 정화를 대체하지 않습니다.
운영 배포 검토 항목
- ✓Markdown 파서 버전을 고정하고 원시 HTML, 플러그인, URL 설정을 검토합니다.
- ✓최종 HTML 삽입 직전에 유지 관리되는 허용 목록 정화기로 생성 HTML을 정화합니다.
- ✓허용 요소, 속성, URL 프로토콜을 필요한 기능으로 제한합니다.
- ✓정화 후 마크업을 수정하거나 다시 파싱하지 않습니다. 변환이 필요하면 이후 다시 정화합니다.
- ✓정확한 파서 설정과 렌더링 삽입 지점을 테스트하고 정화기를 최신 상태로 유지합니다.
자주 묻는 질문
입력 기능 하나를 없애지만 그것만으로 안전성이 입증되지는 않습니다. 링크, 이미지, 확장 기능, 생성 HTML, 삽입 맥락을 검토하고 HTML 삽입 전에 출력을 정화하세요.
피하세요. 이후 변경으로 위험한 마크업이 들어가거나 정화기의 판단이 무효화될 수 있습니다. 변환을 먼저 하고 마지막에 정화하세요.
아닙니다. 문서화된 위협 모델에 따라 HTML 조각에 사용하고 최신 상태를 유지하며 좁은 정책을 적용하세요. JavaScript나 CSS 문자열 등 다른 맥락에서 결과를 재사용하지 마세요.