Vue.js

Reading time: 5 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

Vue.js의 XSS 싱크

v-html 지시어

v-html 지시어는 원시 HTML을 렌더링하므로, 비위생적인 사용자 입력에 포함된 <script> (또는 onerror와 같은 속성)는 즉시 실행됩니다.

html
<div id="app">
<div v-html="htmlContent"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
htmlContent: '<img src=x onerror=alert(1)>'
}
})
</script>

v-bind with src or href

사용자 문자열을 URL을 포함하는 속성(href, src, xlink:href, formaction 등)에 바인딩하면 링크를 따를 때 javascript:alert(1)과 같은 페이로드가 실행될 수 있습니다.

html
<div id="app">
<a v-bind:href="userInput">Click me</a>
</div>
<script>
new Vue({
el: '#app',
data: {
userInput: 'javascript:alert(1)'
}
})
</script>

v-on 사용자 제어 핸들러와 함께

v-onnew Function으로 값을 컴파일합니다. 만약 그 값이 사용자로부터 온 것이라면, 코드 실행을 제공하는 셈입니다.

html
<div id="app">
<button v-on:click="malicious">Click me</button>
</div>
<script>
new Vue({
el: '#app',
data: { malicious: 'alert(1)' }
})
</script>

동적 속성 / 이벤트 이름

사용자가 제공한 이름이 v-bind:[attr] 또는 v-on:[event]에 사용되면 공격자는 정적 분석 및 많은 CSP 규칙을 우회하여 임의의 속성이나 이벤트 핸들러를 생성할 수 있습니다.

html
<img v-bind:[userAttr]="payload">
<!-- userAttr = 'onerror', payload = 'alert(1)' -->

동적 컴포넌트 (<component :is>)

:is에 사용자 문자열을 허용하면 임의의 컴포넌트나 인라인 템플릿을 마운트할 수 있습니다. 이는 브라우저에서 위험하고 SSR에서는 재앙적입니다.

html
<component :is="userChoice"></component>
<!-- userChoice = '<script>alert(1)</script>' -->

SSR에서 신뢰할 수 없는 템플릿

서버 측 렌더링 중에 템플릿은 당신의 서버에서 실행됩니다; 사용자 HTML을 주입하면 XSS가 전체 원격 코드 실행(RCE)으로 확대될 수 있습니다. vue-template-compiler의 CVE는 이 위험을 증명합니다.

js
// DANGER – never do this
const app = createSSRApp({ template: userProvidedHtml })

Filters / render functions that eval

레거시 필터가 렌더 문자열을 생성하거나 사용자 데이터에 대해 eval/new Function을 호출하는 것은 또 다른 XSS 벡터입니다—이를 계산된 속성으로 교체하십시오.

js
Vue.filter('run', code => eval(code))   // DANGER

Vue 프로젝트의 다른 일반적인 취약점

플러그인에서의 프로토타입 오염

일부 플러그인(예: vue-i18n)의 Deep-merge 헬퍼는 공격자가 Object.prototype에 쓸 수 있도록 허용했습니다.

js
import merge from 'deepmerge'
merge({}, JSON.parse('{ "__proto__": { "polluted": true } }'))

vue-router를 이용한 오픈 리다이렉트

검증되지 않은 사용자 URL을 router.push 또는 <router-link>에 전달하면 javascript: URI 또는 피싱 도메인으로 리다이렉트될 수 있습니다.

js
this.$router.push(this.$route.query.next) // DANGER

Axios / fetch의 CSRF

SPAs는 여전히 서버 측 CSRF 토큰이 필요합니다; SameSite 쿠키만으로는 자동 제출된 교차 출처 POST를 차단할 수 없습니다.

js
axios.post('/api/transfer', data, {
headers: { 'X-CSRF-TOKEN': token }
})

Click-jacking

Vue 앱은 X-Frame-Options: DENYContent-Security-Policy: frame-ancestors 'none'를 모두 전송하지 않으면 프레임에 포함될 수 있습니다.

http
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none';

Content-Security-Policy pitfalls

전체 Vue 빌드는 unsafe-eval이 필요합니다; 위험한 소스를 제거할 수 있도록 런타임 빌드나 미리 컴파일된 템플릿으로 전환하세요.

http
Content-Security-Policy: default-src 'self'; script-src 'self';

Supply-chain attacks (node-ipc – March 2022)

node-ipc의 파괴는 Vue CLI에 의해 발생했으며, 전이 종속성이 개발 머신에서 임의의 코드를 실행할 수 있는 방법을 보여주었습니다. 버전을 고정하고 자주 감사하세요.

shell
npm ci --ignore-scripts   # safer install

하드닝 체크리스트

  1. 모든 문자열을 정화하여 v-html에 도달하기 전에 처리합니다 (DOMPurify).
  2. 허용된 스킴, 속성, 컴포넌트 및 이벤트를 화이트리스트합니다.
  3. eval과 동적 템플릿을 완전히 피합니다.
  4. 의존성을 매주 패치하고 권고 사항을 모니터링합니다.
  5. 강력한 HTTP 헤더를 전송합니다 (CSP, HSTS, XFO, CSRF).
  6. 감사, 잠금 파일 및 서명된 커밋으로 공급망을 잠급니다.

참고자료

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기