富文本安全(防御存储型XSS攻击)---DOMPurify库使用

574 阅读1分钟

背景:

最近公司saas系统做了个渗透测试,有一项是富文本安全相关的,需要在富文本字符串之前过滤掉一下恶意脚本之类的。这里用到了一个DOMPurify的库来过滤。

环境:node14.17 技术栈:vue3+ts

安装: npm:

npm install dompurify;

yarn:

yarn add dompurify;

引入

import DOMPurify from 'dompurify';

模拟XSS攻击(直接返回未过滤的html字符串):

const cleanHTML = computed(() => {
	return article.value?.content + '<img src="http://www.123.com/114514.js" onerror=alert(1)>'
})

过滤前: 企业微信截图_17062539938471.png })

浏览器解析到img的src属性中的内容时,发起网络请求获取114514.js文件,但是文件并不存在,所以拿不到

image.png

img标签的src属性拿不到东西,触发onerror事件,出现弹窗

企业微信截图_17062595745428.png

img标签渲染失败

image.png

审视元素发现有问题的img元素

加入过滤代码:

//这里的DOMPurify.sanitize已经可以过滤onerror之类的事件触发的恶意行为了,因为DOMPurify.sanitize本身就有默认的配置
const cleanHTML = computed(() => {
	let str = article.value?.content + '<img src="http://www.123.com/114514.js" onerror=alert(1)>'
	return DOMPurify.sanitize(str)
})

过滤通过img标签请求js文件

import DOMPurify from 'dompurify';
DOMPurify.addHook('uponSanitizeAttribute', function (node: any, attr: any) {
	//检查src属性,如果 src 属性的值是一个 JavaScript 文件的 URL,那么就移除这个属性。
	const regex = /^https?:\/\/.*\.js$/;//正则查询属性值是否为获取js文件的url
	if (attr.attrName === 'src' && node.nodeName === 'IMG' && regex.test(attr.attrValue)) {
		attr.attrName = ''
		attr.attrValue = ''
		attr.keepAttr = false;//是否保留这个属性
	}
});

在addHook的方法中uponSanitizeAttribute事件他是没有返回值的(之前问过gpt说有返回值。。。,详细ctrl+左键点击查看index.d.ts文件)。所以这里直接修改attr对象的属性

过滤后:

image.png 弹窗和渲染失败的img都没了

image.png

浏览器也没获取114514.js文件

image.png 审视元素发现有问题的img标签无了