개요
Vue는 세분화된 반응성을 갖춘 웹 애플리케이션을 개발하기 위한 HTML, CSS 및 JS 프레임워크입니다.
Vue 2 템플릿 컴파일러에서 크로스 사이트 스크립팅(XSS) 취약점이 발견되었으며, 이는 Vue 2의 "전체 빌드"에 존재합니다. 전체 빌드를 사용하면 사용자 코드가 문자열 템플릿을 Vue 컴포넌트로 컴파일하고 브라우저 내에서 함수를 동적으로 렌더링한 다음 실행할 수 있습니다.
OWASP 기준: 크로스 사이트 스크립팅 공격은 악성 스크립트가 정상적이고 신뢰할 수 있는 웹사이트에 삽입되는 인젝션의 한 유형입니다. XSS 공격은 공격자가 웹 애플리케이션을 사용하여 일반적으로 브라우저 측 스크립트 형태의 악성 코드를 다른 최종 사용자에게 전송할 때 발생합니다. 공격자는 XSS를 사용하여 의심하지 않는 사용자에게 악성 스크립트를 보낼 수 있습니다.
세부 정보
모듈 정보
- 패키지 관리자: npm
- 영향을 받는 패키지: vue-template-compiler
- Affected versions: >= 2.0.0 < 3.0.0
- 게시된 패키지 링크: https://www.npmjs.com/package/vue-template-compiler
- 깃허브 리포지토리: https://github.com/vuejs/vue
- 개념 증명: https://stackblitz.com/edit/cve-2024-6783?file=index.html
취약점 정보
This Medium-severity level exploit can be found in Vue versions greater than or equal to 2.0.0 and before 3.0.0. It is found inside of the in-browser Vue template compiler which is shipped inside the “full build” of Vue. The in-browser Vue template compiler is responsible for creating a string of code to be executed so that component templates like “<div>{{ variables }}</div>” can be parsed and turned into render functions. These render functions are then executed by Vue when it evaluates the render functions within a stringified eval statement, thus allowing a third-party script to run arbitrary code.
Object.prototype을 확장할 때 특정 속성만 클라이언트 측 XSS 취약성에 취약합니다. 이러한 속성 중 하나는 템플릿 문자열이 비동적 클래스와 함께 `class` 속성을 사용할 때 AST 구성 단계에서 검색되는 staticClass입니다.
전체 템플릿 문자열에 따라 이 코드 경로를 트리거할 수도 있고 트리거하지 않을 수도 있는 최적화가 적용되어 있습니다. 이 공격에 취약한 컴포넌트의 예는 '재현 단계'를 참조하세요.
재현 단계
Vue의 브라우저 내 템플릿 컴파일러를 위한 AST Codegen 경로는 처음에 설정되지 않은 프로퍼티에 의존합니다. 결국 프로퍼티는 값을 문자열화하여 렌더링 중에 평가 문으로 전달하는 함수에 의해 사용됩니다. 이러한 프로퍼티가 명시적으로 정의되지 않은 것으로 설정되거나 hasOwnProperty를 확인했다면 프로토타입 오염이 발생하지 않았을 것입니다. 현재 ASTElement(SSR, 브라우저 내 컴파일 및 Vue SFC 파일 파서에서 코드젠 노드를 생성하는 데 사용되는 기본 데이터 구조)의 거의 모든 프로퍼티는 선택 사항이며 이 XSS 취약점에 취약할 수 있습니다.
크로스 사이트 스크립팅 공격은 멀쩡하고 신뢰할 수 있는 웹사이트에 악성 스크립트를 삽입하는 인젝션의 한 유형입니다. XSS 공격은 공격자가 웹 애플리케이션을 사용하여 일반적으로 브라우저의 형태로 악성 코드를 전송할 때 발생합니다. 템플릿 컴파일러 코드는 AST를 소비하고 렌더링 중에 최종적으로 호출되는 속성에 배치될 콘텐츠를 적절하게 살균하지 않습니다. 다음 섹션의 예제 코드와 개념 증명은 완전한 것은 아닙니다.
<head>
<script>
window.Proxy = undefined // Not necessary, but helpfull in demonstrating breaking out into `window.alert`
Object.prototype.staticClass = `alert("Polluted")`
</script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
new window.Vue({
template: `<div class="">Content</div>`,
}).$mount('#app')
</script>
</body>
개념 증명
개념 증명 웹사이트의 위 코드가 포함된 전체 복제본은 여기에서 확인할 수 있습니다: https://stackblitz.com/edit/cve-2024-6783?file=index.html
완화
Vue 2의 수명이 종료되었습니다. 영향을 받는 구성 요소의 사용자는 다음 완화 조치 중 하나를 적용해야 합니다:
- 최신 버전의 Vue로 마이그레이션하기
- 자체 패치 적용
- 히어로데브즈와 같은 상용 지원 파트너를 활용하여 EOL 이후 보안 지원을 받으세요.
크레딧
- 지펑 강 찾기
- 무시 류 파인더
- 인지 카오
저희가 지원하는 오픈 소스 소프트웨어에서 새로운 취약점이 수정될 때마다 알림을 받으세요.