非常抱歉,我必须这么做,因为我在工作的网站上发现了一个可能可利用的安全问题,我会用新帐户发布此内容。
我们有一个脚本来接收用户评论(所有评论都是英文)。过去两年中,我们已经积累了大约3,000,000个评论。我正在检查评论表是否存在任何恶意行为的迹象,这一次我扫描了撇号字符。在所有情况下,它应该被转换为HTML实体('
),但我发现了18条记录(300万条评论中的18条记录)中该字符幸存了。真正困扰我的是,在这18个评论中,有一个撇号实际上被成功转换了 - 另一个幸存了。
这对我来说表示我们可能有一个XSS漏洞。
我对于发生了什么的理论是:用户在使用非西方代码页的计算机系统上访问页面,并且他们的浏览器忽略了我们页面的utf-8字符集规范,直到输入到达数据库之前,其输入没有被转换为服务器的本地代码页(因此C#无法识别该字符为撇号,因此无法将其转换,但是当尝试将其写入LATIN1表时,数据库可以)。但这只是一个猜测。
有人遇到过这种情况吗?或者知道发生了什么?
更重要的是,有人知道我该如何测试我的脚本吗?切换到HttpUtility
可能会修复此问题,但在我知道发生了什么之前,我无法确定问题是否已经解决。我需要能够测试此功能以确保我们的解决方案有效。
编辑
哇,已经有20个点,所以我可以编辑我的问题了。
我在其中一个评论中提到,我发现了几个似乎存在问题的字符。它们包括:0x2019、0x02bc、0x02bb、0x02ee、0x055a和0xa78c。这些字符能够通过我们的过滤器。不幸的是,它们也能够通过所有 HttpUtility 编码方法。但是一旦它们被插入数据库,它们会被转换成实际的撇号或“?”。
回顾一下,我认为问题在于这些字符本身并没有构成威胁,所以 HttpUtility 没有理由将它们转换。在 JavaScript 代码块中,它们是无害的。在 HTML 代码块中,它们只是字符数据,也是无害的。在 SQL 代码块中,它们也是无害的(如果数据库共享相同的编码页)。对我们来说的问题是,因为我们在数据库中使用的编码页不同,插入过程会将这些“不可打印”字符转换为“已知等价物”(在这种情况下是“劣质”的)和“未知等价物”(渲染为“?”)。这完全出乎我们的意料,我有点失望微软没有在他们的 HttpUtility 编码函数中做更多的工作。
我认为解决方案是更改受影响表的排列规则。但如果有其他更好的想法,请在下面发表评论。
XSS
攻击。只需使用HttpUtility.HtmlEncode
,并将其留给ASP.NET安全团队(希望他们能看到这个问题)。 - Xaqron