Data URL 在 Vue 中如何安全地用于图片 src 防 XSS?

丽珍 阅读 23

我在 Vue 项目里用用户上传的 base64 图片直接赋值给 img 的 src,担心会有 XSS 风险。比如下面这样写:

<template>
  <img :src="userProvidedDataUrl" alt="preview" />
</template>

<script>
export default {
  data() {
    return {
      userProvidedDataUrl: 'data:image/png;base64,...' // 来自不可信输入
    }
  }
}
</script>

虽然浏览器一般不会执行 data URL 里的脚本,但听说某些旧版本或特殊 MIME 类型可能有漏洞。我该怎么做才能确保安全?要不要先校验 MIME 类型?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
钰欣
钰欣 Lv1
按照规范,data URL 本身不会执行脚本,但确实存在 MIME 类型欺骗的风险,比如用户上传一个 HTML 文件却声明为 data:image/png;base64,...,在某些旧浏览器或特殊场景下可能被当作文档解析,引发 XSS。

稳妥的做法是:服务端校验 MIME 类型 + 客户端二次过滤。

服务端要严格校验上传文件的真实类型(比如通过文件头 magic number),不能只信客户端传来的 MIME 类型;客户端 Vue 里可以再做一层简单校验,比如用正则匹配 base64 前缀是否合法,或者用 atob 解码后检查前几个字节是否符合图片格式(PNG 是 89 50 4E 47)。

但如果你只是做前端预览,不存储也不转发,风险其实低很多,不过按规范还是建议加上白名单限制:

const ALLOWED_MIME_TYPES = ['image/png', 'image/jpeg', 'image/gif', 'image/webp']

function isValidDataUrl(url) {
if (typeof url !== 'string' || !url.startsWith('data:')) return false
const match = url.match(/^data:([^;,]+);base64,/)
if (!match) return false
const mimeType = match[1].trim().toLowerCase()
return ALLOWED_MIME_TYPES.includes(mimeType)
}


然后在 beforeMountwatch 里校验:

userProvidedDataUrl = isValidDataUrl(rawInput) ? rawInput : ''

另外别忘了设置 imgalt 属性,虽然不防 XSS,但符合无障碍规范,也算基础安全意识。
点赞
2026-02-23 23:07