Vue 安全实践:XSS 防护之动态 Option 过滤

什么是 XSS 攻击?

XSS(Cross-Site Scripting)跨站脚本攻击是一种常见的网络安全漏洞,攻击者通过在网页中注入恶意脚本,当其他用户浏览该网页时,脚本会在用户浏览器中执行,从而窃取用户数据或进行其他恶意操作。

在 Vue 中使用 ECharts 时,如果直接将用户输入的数据用于图表配置(特别是 tooltip 等富文本场景),就可能存在 XSS 风险。

Vue 中的 XSS 防护机制

Vue 本身提供了一些基础的 XSS 防护:

  • 文本插值({{ }})会自动转义 HTML
  • v-html 指令需要显式使用,提醒开发者潜在风险

但在 ECharts 配置中,特别是 tooltip 的富文本形式,这些防护可能失效:

// 危险示例:直接使用用户输入
option = {
  tooltip: {
    formatter: userInput // 如果 userInput 包含恶意脚本,会被执行
  }
}

动态 Option 的 XSS 防护方案

1. 输入过滤与净化

使用专门的库对用户输入进行过滤:

import DOMPurify from 'dompurify';

const safeOption = {
  tooltip: {
    formatter: DOMPurify.sanitize(userInput)
  }
}

2. 内容转义处理

对于不需要 HTML 的场景,进行完全转义:

function escapeHtml(unsafe) {
  return unsafe
    .replace(/&/g, "&")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}

option = {
  tooltip: {
    formatter: escapeHtml(userInput)
  }
}

3. 白名单控制

对于需要部分 HTML 的场景,实现白名单机制:

const allowedTags = ['b', 'i', 'br'];
const allowedAttributes = { b: ['class'], i: [] };

function sanitizeWithWhitelist(input) {
  // 实现白名单过滤逻辑
  // ...
}

实践建议

  1. 防御层级

    • 前端做防护是最后一道防线
    • 后端接口也应该对数据进行过滤
  2. 工具选择

    • 推荐使用成熟的库如 DOMPurify
    • 避免自己编写复杂的过滤逻辑
  3. 性能考虑

    • 对于高频更新的数据,考虑缓存净化结果
    • 在 Web Worker 中进行繁重的净化操作
  4. Vue 特定实践

    • 将净化逻辑封装为自定义指令或过滤器
    • 对于复杂场景,使用渲染函数而非模板
// 自定义指令示例
Vue.directive('safe-html', {
  inserted: function(el, binding) {
    el.innerHTML = DOMPurify.sanitize(binding.value);
  },
  update: function(el, binding) {
    el.innerHTML = DOMPurify.sanitize(binding.value);
  }
});

总结

在 Vue 中使用 ECharts 时,特别是处理动态 option 和富文本内容时,XSS 防护不容忽视。通过输入过滤、内容转义和白名单控制等多层防护,可以有效降低安全风险。记住,前端安全防护是系统工程,需要与其他安全措施配合使用才能达到最佳效果。

评论已关闭