flawopen.com/JavaScript XSS/Vue v-html
Vue v-html XSS 위험과 안전한 사용법
Vue의 {{ comment }} 보간은 인용된 쪽지를 유리 너머로 보여주는 것과 같습니다. 꺾쇠도 텍스트로 남습니다. v-html은 브라우저에 쪽지를 HTML로 열라고 요청합니다. 사용자가 마크업을 제어하면 브라우저가 이를 페이지 구조나 활성 콘텐츠로 처리해 XSS 위험을 만들 수 있습니다.
<p v-html="comment"></p>
// comment가 실제 마크업으로 해석됨
<script setup>
import { computed } from 'vue'
import DOMPurify from 'dompurify'
const props = defineProps({ comment: String })
const safeComment = computed(() =>
DOMPurify.sanitize(props.comment ?? '', {
ALLOWED_TAGS: ['p', 'strong', 'em'],
ALLOWED_ATTR: []
})
)
</script>
<template>
<div v-html="safeComment"></div>
</template>
v-html 전에 리치 HTML 정제
내용이 텍스트여야 한다면 Vue의 {{ }} 보간을 우선 사용하세요. 사용자 작성 리치 HTML이 꼭 필요한 기능에서는 DOMPurify 같은 유지 관리되는 라이브러리를 좁은 허용 목록으로 사용하고, 정제된 결과만 v-html에 바인딩하세요. 새니타이저를 최신 상태로 유지하고 허용 마크업 정책을 테스트하세요. 정제는 위험을 낮출 뿐 모든 HTML을 모든 맥락에서 안전하게 만들지는 않습니다. 신뢰할 수 없는 활성 콘텐츠를 표시해야 하면 격리된 iframe을 사용하세요. Vue는 v-html 내용을 Vue 템플릿으로 컴파일하지 않습니다.
v-html 감사 및 데이터 흐름 추적
모든 v-html 바인딩을 검색하세요. 각 항목의 출처, 새니타이저와 설정, 렌더링된 내용을 볼 수 있는 사용자를 확인합니다. 직접 사용자 입력, 저장된 댓글, CMS 필드, API 응답을 표시하고 일반 텍스트는 보간을 사용하는지 확인하세요.
grep -rn "v-html" --include="*.vue" .자주 묻는 질문
둘 다 프레임워크의 일반 텍스트 이스케이프 경로를 우회해 HTML을 DOM에 삽입합니다. 리치 HTML이 필요하면 유지 관리되는 새니타이저를 사용하고 정제된 결과를 모든 맥락에서 안전하다고 간주하지 마세요.