根据我阅读的一篇文章,全球 65% 的网站都患有 XSS。为什么开发人员找不到并修复它?
请帮我理解。我不是来自安全或技术背景。
根据我阅读的一篇文章,全球 65% 的网站都患有 XSS。为什么开发人员找不到并修复它?
请帮我理解。我不是来自安全或技术背景。
XSS 是一种代码注入形式,即攻击者设法将自己的恶意代码(通常是 JavaScript)注入到站点提供的可信代码(HTML、CSS、JavaScript)中。它与SQLi的相似之处在于它是由动态构造的代码(即 SQL 语句、HTML 页面等)引起的。
但是,虽然有成熟的技术可以解决 SQLi(即使用参数绑定),但使用 XSS 更加困难。为了防御 XSS,每个用户控制的输入都必须正确转义,这比听起来要困难得多:
<a href=javascript:XXX
> 是 HTML 属性内的 URL 上下文内的 JavaScript 上下文。虽然有一些简单的方法可以通过设计(尤其是 Content-Security-Policy)来防止 XSS,但这些方法仅适用于最新的浏览器,必须由开发人员明确启用,并且通常只有在对代码(如删除内联脚本)。
但是,如果您的开发人员具有适当的知识并且能够使用已经处理 XSS 的现代工具包从头开始,那么仍然有很好的机会做正确的事。不幸的是,在许多情况下,遗留代码只是需要继续处理。开发通常由完全不了解 XSS 或不知道所有陷阱的开发人员完成。
只要 Web 开发是在对成本和时间非常敏感的环境中完成的,这种情况发生变化的可能性就很小。这种环境的目标是使代码在短时间内以较低的成本运行。公司通常根据功能和上市时间进行竞争,而不是根据谁是最安全的产品。而 XSS 保护目前只是意味着额外的成本,对许多经理来说没有明显的好处。
首先,攻击面巨大。如果您想在任何地方以 HTML 格式显示用户输入,则需要处理 XSS。这是几乎所有网站都会做的事情,除非它们纯粹是用静态 HTML 构建的。
结合这一事实,虽然 XSS 似乎很容易处理,但事实并非如此。OWASP XSS 预防备忘单长达4000 字。你需要一张相当大的纸来装下所有的文字。
复杂性的出现是因为 XSS 在不同的上下文中的工作方式不同。如果您在 JavaScript 中插入不受信任的数据,您需要做一件事,如果您插入到属性值中,则需要做一件事,如果您在标签之间插入,则需要做另一件事,等等。OWASP 列出了六个不同的上下文,它们都需要不同的规则,加上一些上下文永远不应该插入数据的地方。
与此同时,开发人员一直在寻找灵丹妙药和灵丹妙药。他们希望将所有艰苦的工作都转移到一个sanitize()
函数上,他们总是可以调用不受信任的数据,每天收工,然后继续进行真正的编程。但是,尽管已经编写了许多这样的函数,但它们都不起作用。
让我重复一遍:XSS 似乎很容易处理,但事实并非如此。主要的危险在于这句话的第一部分,而不是第二部分。感知的简单性鼓励开发人员制作他们自己的自制解决方案——他们自己的个性化sanitize()
功能,充满了概括、不完整的黑名单和错误的假设。你在 URL 中过滤掉了javascript:
,但你有没有想过vbscript:
?或者javaSCripT :
?您对引号进行了编码,但您是否记得实际上将属性值括在引号中?那么字符编码呢?
情况与 SQLi 非常相似。每个人都一直在寻找一种卫生功能来统治他们所有人,无论是addslashes
命名mysql_escape_string
还是mysql_real_escape_string
. 这是货物崇拜安全,人们认为在仪式上调用正确的功能来安抚众神就足够了,而不是真正接受问题的复杂性。
所以危险不在于开发人员完全不知道 XSS。是他们认为他们控制了局势,因为嘿,我为它编写了一个函数。
Web 面临的问题是结构 (HTML)、表示 (CSS) 和动态 (JavaScript) 都混合成我们放入.html
文件中的长字符串。这意味着您可以跨越许多界限以从一种环境转移到另一种环境。
同样,这与 SQLi 相同。在那里,您将指令和参数值混合在一个字符串中。为了停止 SQLi,我们发现我们必须将两者完全分开,并且永远不要混合它们 - 即使用参数化查询。
XSS 的解决方案类似:
我们创建了一个简单的方法来完成第二部分 -内容安全策略。您需要做的就是设置一个 HTTP 标头。但第一部分很难。对于旧的 Web 应用程序,完全重写可能比通过手术将脚本从 HTML 中分离出来更容易。因此,依靠这种魔力sanitize()
并希望获得最好的结果会更容易。
但好消息是,较新的应用程序通常是在可能使用 CSP 的更严格原则之后开发的,并且现在几乎所有浏览器都支持它。我并不是说我们要把易受攻击的网站的百分比降到 0%,但我希望在未来几年它会从 60% 下降很多。
TL;DR:这变成了相当长的咆哮。不确定这里是否有很多有用的信息 - 如果您想进行清晰的分析,请阅读 Steffen Ullrichs 的精彩回答。
我对安全和 XSS 的看法:
正如您对类似帖子的回答中提到的(SQL 注入已有 17 年历史。为什么它仍然存在?):
SQLi 没有通用的修复方法,因为人类的愚蠢没有修复方法
开发人员有时会变得懒惰或粗心,这导致他们不检查他们正在开发的应用程序。
另一个流行的原因是开发人员没有意识到存在安全问题。他们从未接受过任何安全培训,因此他们不知道什么是潜在的安全威胁,什么不是。对于那些不了解渗透测试很重要的公司来说,缺乏安全知识本身就是一个潜在的威胁。
只有当公司决定花时间进行代码审查和测试时,SQLI 和 XSS 等简单的安全问题才会得到解决。在此之前,全球 65% 的网站都存在 XSS 漏洞。