xss库过滤后内容变空白是怎么回事?

Mr-熙然 阅读 96

我用 xss 库对用户输入做过滤,但有些内容直接变成空字符串了,比如输入 alert(1) 确实该被清掉,但像 test 这种,为啥连 “test” 都没了?

我试过默认配置和自定义白名单,还是不行。代码是这样:

const clean = xss('<img src="a" onerror="alert(1)">test');
console.log(clean); // 输出居然是空字符串!
我来解答 赞 14 收藏
二维码
手机扫码查看
2 条解答
令狐怡萱
这个问题听起来挺头疼的。xss 库的默认行为有时候确实会让人摸不着头脑。咱们一步一步来排查一下。

首先,xss 库在处理 HTML 内容时,默认情况下会移除所有它认为可能存在安全风险的标签和属性。这包括像 onerror 这样的事件处理器,因为你提到的 alert(1) 显然是一个 XSS 攻击的例子。

但是,test 变为空字符串可能是因为默认的解析器在处理 标签的时候,发现这个标签不合法或者不完整(因为它没有闭合标签),所以它可能把整个 标签及其后面的内容都忽略了。

解决这个问题的方法之一是确保你的 HTML 输入是有效的,不过有时候这是不可能控制的,特别是当用户输入的时候。另一个方法是调整 xss 库的配置,让它更宽松一些,允许通过我们信任的内容。

下面我给你一个自定义配置的例子,让 xss 库能够通过 test 这样的纯文本内容:

const xss = require('xss');

// 自定义白名单,允许 img 标签,但是移除 onerror 属性
const myXssFilter = new xss.FilterXSS({
whiteList: {
img: ['src'] // 只允许 src 属性
}
});

const input = 'test';
const clean = myXssFilter.process(input);
console.log(clean); // 应该输出: test


这里我们创建了一个新的 FilterXSS 实例,并且定义了一个 whiteList,只允许 img 标签并且只保留它的 src 属性。这样就不会移除 test 了。

原理是这样:通过自定义白名单,我们可以告诉 xss 库哪些标签和属性是可以信任的,哪些应该被移除。这样既可以保护我们的应用不受 XSS 攻击,又能保留我们想要的内容。

希望这能解决你的问题。有时候处理这种库的行为确实挺费劲的,但是一旦搞定了,心里还是会挺有成就感的。
点赞
2026-03-23 23:02
司马欣怡
这个问题挺诡异的,默认情况下 xss 库不应该把 "test" 也给你清掉。

你先打印一下原始输入看看:

const input = '<img src="a" onerror="alert(1)">test';
console.log('原始输入:', input);
console.log('输入长度:', input.length);


我怀疑你输入的字符串本身可能有问题。你代码里写的是 xss('test'),但看问题详情你贴的是 xss(''<img src="a" onerror="alert(1)">test''),这可是 HTML 实体编码后的内容啊。

如果是实体编码的情况,xss 库会把它当普通文本处理,不会做过滤,最后输出应该和输入一样。你试试直接输出那个带 < 的字符串,看看是不是本来就长这样。

如果排除编码问题,那就检查一下你的 xss 配置:

const xss = require('xss');
const clean = new xss.FilterXSS({
whiteList: {}, // 你是不是设了空白名单?
stripIgnoreTag: true,
stripIgnoreTagBody: ['script']
});

console.log(clean.process('<img src="a" onerror="alert(1)">test'));


你配置里是不是把 whiteList 设成空对象了?那所有标签都会被干掉的。

另外还有一种情况:有些版本或者用法下,如果整个字符串被识别为危险内容,可能会返回空串。你可以先试试不过滤直接输出原字符串,确认问题到底出在哪一步。
点赞
2026-03-18 15:25