vue指令v-bind中DOM 型 XSS 攻击

379 阅读1分钟

在vue项目中我们经常会使用v-bind指令绑定对应的方法或属性,让组件或DOM元素能够解析或读取动态数据,从而实现我们需要的功能,但是如果绑定直接使用了用户输入信息,很可能会引起xss攻击,从而导致普通用户遭受莫名损失,下面我们列举一下常见的xss攻击方式

1. 排查 v-htmlinnerHTMLouterHTMLdocument.write的使用,判断是否有用户挟持的可能

示例:

<template>  
<div :innerHTML="attackUrl"></div>  
</template>  
  
<script setup>  
import {ref} from "vue";  
const attackUrl = ref('<img src="" onerror="alert(`xss`)">')  
</script>  
  
<style lang="less" scoped>  
</style>

运行结果:

image.png

2. 排查onclickonerroronloadonmouseoverhref的使用,判断是否有用户挟持的可能,一般情况以上方法均属于内部方法,不应被外部用户所挟持和干扰

示例:

<template>  
<a :href="attack">abc</a>  
</template>  
  
<script setup>  
const attack = 'javascript: alert("href xss")'  
</script>  
  
<style lang="less" scoped>  
</style>

运行结果:

image.png

3. 排查eval()setTimeout()setInterval()能把字符串作为代码运行的使用,判断是否有使用的必要以及挟持的可能性,正常来说eval是当前项目编码中严禁使用的方法

<template>  
<div>setTimeout</div>  
</template>  
  
<script setup>  
const outsideAttack = 'alert("outside xss")'  
setTimeout(outsideAttack, 100)  
</script>  
  
<style lang="less" scoped>  
</style>

运行结果:

image.png

4、针对使用了很广泛的elemmentUI组件库,排查$comfirm$alert$prompt是否有用户挟持的可能,尽量避免外部输入的直接交互

<template>  
<div>$alert</div>  
</template>  
  
<script setup>  
import { ElMessage, ElMessageBox } from 'element-plus'  
ElMessageBox.alert('<a href="javascript: alert(`xss`)"><strong>这是 <i>HTML</i> 片段 </strong></a>', 'HTML 片段', {  
dangerouslyUseHTMLString: true  
});  
</script>  
  
<style lang="less" scoped>  
</style>

运行结果:

image.png

推荐解决方案:

  • 针对v-html,可以使用第三方库dompurify进行转义输出
<template>  
<div v-html="safeHtml"></div>  
</template>  
  
<script setup>  
import {ref} from "vue";  
import DOMPurify from 'dompurify';  
const dirtyHtml = ref(`<a href="javascript: alert('xss')">这是安全的文本</a>`);  
const safeHtml = ref('');  
  
// 使用DOMPurify清洗HTML  
safeHtml.value = DOMPurify.sanitize(dirtyHtml.value);  
</script>
  • HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie
  • 合理设置Content Security Policy,禁止外域代码加载