Vue3中防御XSS攻击的“特效药”-DOMPurify

一、快速入门

1.1 DOMPurify 概述

  在 JavaScript 开发的世界中,安全性是保护应用程序免受潜在威胁和漏洞的至关重要。在 Vue 3 应用中渲染动态 HTML 内容时,安全风险不容忽视。DOMPurify 是一个开源的基于 DOM 的快速 XSS 净化工具,专门用于净化HTML、MathML和SVG,能有效防御跨站脚本攻击(XSS攻击)。它通过解析递归元素节点来净化 HTML,输出安全的 HTML 内容,能够有效抵御防止XSS攻击。

1.2 DOMPurify 核心思路

  DOMPurify 的核心思想是:不要自己写 HTML 解析器,而是让浏览器来解析

graph LR A["恶意 HTML 字符串"] A-->B["浏览器 DOM 解析器"] B-->C["DOM 树"] C-->D["遍历 DOM 树"] D-->E["检查节点"] E--在白名单-->F1["保留"] E--不在白名单-->F2["删除"] F1-->G["安全的 HTML"] F2-->G

1.3 安装与引入

  可以通过 npm 来安装 DOMPurify 库,命令如下:

bash 复制代码
# 确认安装版本(含嵌套依赖)
npm install dompurify

# 或者
yarn add dompurify

  在需要使用 DOMPurify 的文件中导入 DOMPurify 库,代码如下:

javascript 复制代码
import DOMPurify from 'dompurify';

1.4 基础用法

  使用 DOMPurify 库过滤 HTML 非常简单,可以直接调用 DOMPurify.sanitize() 方法,将需要过滤的HTML字符串作为参数传入,然后它就会返回一个消毒过的版本。比如,在表单的提交中,或者需要根据用户改变html内容的时候,净化字符串,放置隐藏恶意脚本。代码示例如下:

javascript 复制代码
import DOMPurify from 'dompurify';

// 示例:可能不安全的HTML输入
let rawHtml = '<p>Safe content</p><scr' + 'ipt>alert("XSS")</scr' + 'ipt>';
let sanitizedHtml = DOMPurify.sanitize(rawHtml);
console.log('DOMPurify过滤前:', rawHtml)
console.log('DOMPurify过滤后:', DOMPurify.sanitize(html))

  在上面的示例中,我们尝试注入一段 JavaScript 代码。然而,DOMPurify 检测到此并删除它,使得输出的 HTML 代码是安全的。

二、DOMPurify 高级配置

  DOMPurify 不仅支持简单的清洗操作,它还提供了详细的配置选项,使得开发人员能够通过配置选项自定义净化规则,以满足不同的安全需求。

2.1 白名单过滤

  可以定义一个配置对象来指定自定义允许的标签和属性。

javascript 复制代码
const config = {
  // 只允许这些HTML标签
  ALLOWED_TAGS: ['p', 'a', 'b', 'i', 'em', 'strong'],
  // 只允许这些HTML属性
  ALLOWED_ATTR: ['href', 'title', 'target'],
  // 允许自定义URI的协议
  ALLOWED_URI_REGEXP: /^(https?|ftp):/i
  // 禁止的危险属性
  FORBID_ATTR: ['onclick', 'onload']
};

const dirtyHtml = '<p>Hello, <a href="https://example.com" target="_blank" οnclick="alert(1)">World</a>!</p>';
const cleanHtml = DOMPurify.sanitize(dirtyHtml, config);

2.2 自定义钩子

  DOMPurify 支持在净化流程的不同阶段插入自定义逻辑,实现高度定制化的安全策略,允许我们在净化过程中进行更细粒度的控制。

钩子函数 简要说明
beforeSanitizeElements 在清理元素前触发,可用于提前移除某些节点或属性
afterSanitizeElements 对节点进行基础清理之后触发,常用于处理链接安全、图片防盗链、强制 HTTPS
uponSanitizeShadowNode
beforeSanitizeAttributes
afterSanitizeAttributes 在清理属性后触发
beforeSanitizeShadowDOM
afterSanitizeShadowDOM
uponSanitizeElement 当遍历到具体的 HTML 元素时触发,可以用来记录日志、监控被拦截的危险标签
uponSanitizeAttribute 在处理具体属性时触发,常用于校验 URL 协议,防止执行恶意的 JavaScript 代码

  例如,可以阻止特定的属性:

javascript 复制代码
DOMPurify.addHook('uponSanitizeAttribute', (node, data) => {
  if (data.attrName === 'src' && /javascript:/i.test(data.attrValue)) {
    data.keepAttr = false; // 阻止javascript:协议
  }
});

三、最佳实践

3.1 查看被移除的内容

  在进行安全审计或调试时,可能需要知道 DOMPurify 移除了哪些内容:

javascript 复制代码
const dirtyInput = '<script>alert("XSS")</script><p>Safe content</p>';
const clean = DOMPurify.sanitize(dirtyInput);

// 查看被移除的节点
console.log(DOMPurify.removed);

请注意,DOMPurify.removed 主要用于调试,不建议在生产环境中依赖它进行业务逻辑判断。

3.2 结合Vue响应式数据

  通常,我们还会将 DOMPurify 与 Vue 的响应式系统(如 ref、computed)结合使用:

html 复制代码
<script setup>
import { ref, computed } from 'vue';
import DOMPurify from 'dompurify';

const userInput = ref('');
const sanitizedInput = computed(() => DOMPurify.sanitize(userInput.value));
</script>

<template>
  <textarea v-model="userInput" placeholder="输入内容"></textarea>
  <div v-html="sanitizedInput"></div>
</template>

3.3 使用自定义指令

  为了更方便地在模板中使用,可以创建一个自定义指令:

javascript 复制代码
// main.js 或类似文件
import { createApp } from 'vue';
import App from './App.vue';
import DOMPurify from 'dompurify';

const app = createApp(App);

app.directive('safe-html', (el, binding) => {
  el.innerHTML = DOMPurify.sanitize(binding.value);
});

app.mount('#app');

  在组件中使用自定义指令:

html 复制代码
<template>
  <div v-safe-html="rawHtml"></div>
</template>

四、总结

  当今数字时代,安全性在应用程序开发中变得愈发重要。为了确保用户数据的保密性、完整性和可靠性,开发人员需要采取各种措施来应对安全挑战。DOMPurify 是 Vue 3 应用中处理不安全 HTML 并防御 XSS 攻击的强力工具。通过其简单的 API 和灵活的配置,它可以满足多种安全需求。关键在于牢记安全需要多层防御,切勿完全依赖客户端净化。

相关推荐
kyriewen2 分钟前
我筛了 1400 个 Claude Code Skills,留下 5 个天天在用的
前端·ai编程·claude
JNX_SEMI17 分钟前
AT2401C 2.4GHz 全集成射频前端单芯片技术解析
前端·单片机·嵌入式硬件·物联网·硬件工程
anOnion35 分钟前
Agentic 前端开发之 实时显示 AI Agent 终端输出
前端·javascript·人工智能
随风一样自由1 小时前
【前端领域】2026最新前端领域全梳理(框架/工具/AI/跨端/底层标准/就业趋势)
前端·人工智能·前端框架
这是个栗子1 小时前
【前端性能优化】优化数据加载:用 Promise.all 从串行到并行
前端·javascript·性能优化·异步编程·前端优化·promise.all
fei_sun1 小时前
黑洞路由(Null Route/空接口路由)
服务器·前端·javascript
大爱一家盟2 小时前
告别卡点BGM同质化 2026原创卡点音乐素材下载网站 TOP5 推荐
大数据·前端·人工智能
彦为君2 小时前
算法思维与经典智力题
java·前端·redis·算法
云水一下2 小时前
DVWA从入门到精通(四):CSRF(跨站请求伪造)
安全·csrf·dvwa
tuddy7894642 小时前
Codex++ 安全边界探秘:从模型能力到风险防御
人工智能·python·安全