设置 document.title 时限制后一种基于 dom 的 XSS

信息安全 xss javascript dom
2021-08-27 07:39:30

给定一些通过接收可变数据来修改页面标题的 JavaScript

document.title = someVariable

我希望解决基于 dom 的 XSS,同时保持标题的可读性。因此,做类似escape()encodeURI()不会工作的事情。

我不一定可以控制 document.title 在其他脚本中的使用方式,因此我想确保在破坏最少的情况下进行一些清理,但要避免以后处理变量的方式可能会出现的情况以这种方式解码,它后来成为 XSS。

我的第一个想法是这样的:

someVariable = someVariable.replace('<script', 'noscript');
someVariable = someVariable.replace(/[<>'"]/g, '').replace(/%3[CEce]/, '');
document.title = someVariable;

从可读性的角度来看,这具有最小的破坏性,删除这些字符可能会破坏后面的代码,但我宁愿为了安全而破坏代码。

我觉得我在这里滚动自己,所以我想知道是否有更好的方法可以满足可读性要求。如果没有,是否有任何其他过滤器或消毒推荐?

2个回答

如果您需要采用这种方法,那么为什么不删除除字母数字和空格字符之外的所有内容呢?即去白名单而不是黑名单。您不知道 HTML 和 JavaScript 中的标准将来会如何变化,因此只允许可能是好的字符而不是不允许已知的坏字符。

我不一定可以控制 document.title 在其他脚本中的使用方式,因此我想确保在破坏最少的情况下进行一些清理,但避免以后处理变量的方式可能会发生的情况以这种方式解码,它后来成为 XSS。

我的问题是,谁有控制权?当然,处理此问题的正确方法是在输出到页面时正确输出编码 - 我只是想知道为什么这不是您的系统可接受的解决方案。如果你不能控制其他脚本,你怎么知道它们在其他方面是安全的?

替换<script>不会停止嵌入脚本。还有很多其他注入脚本的方法。例如

<img src="x" onerror="alert('xss')" />

最好的解决方案是将某些字符和序列(递归)列入黑名单。这完全取决于您愿意为安全性牺牲多少可用性。您可以将脚本标签列入黑名单,并且有人可以使用 img src=# onerror 等。如果这些序列不是预期的,那么这样做不会有什么坏处,但我不知道您的应用程序的用途。

我相信您所做的并不好,但这是这里可能的最佳方法。