利用表单劫持绕过CSP | PortSwigger研究
Gareth Heyes
研究员
@garethheyes
发布时间: 2024年3月5日 14:55 UTC
更新时间: 2024年3月5日 14:55 UTC
在这篇文章中,我们将向您展示如何通过一种经常被忽视的技术来绕过CSP,这种技术可以在看似安全的配置中实现密码窃取。
什么是表单劫持?
表单劫持并不是一个广为人知的技术;其核心思想是当您存在受CSP保护的HTML注入漏洞时,利用formaction属性或注入自己的表单将数据发送到攻击者的服务器。过度积极的密码管理器还会帮助填充注入输入框的凭据,使得这种攻击变得相当严重。
实际案例
我们在Infosec Mastodon上发现了一个真实案例,他们使用的Mastodon分支没有正确过滤HTML。攻击者随后可以使用表单劫持,在Chrome密码管理器自动填充凭据后将其发送到自己的服务器。最终结果是用户会在Infosec Mastodon上看到一个帖子,点击看似界面的一部分,实际上却将用户的凭据发送到攻击者的服务器。
那是一年多前的事情,然后…我们收到了Johan Carlsson向我们漏洞赏金计划提交的优秀报告。
在报告中,他展示了我们如何将某些Google脚本资源加入白名单,以及他如何通过注入AngularJS来利用这一点绕过CSP。在我们修复之后,他还指出我们没有防范表单劫持!幸运的是,这仅仅是我们CSP的一个绕过,因为我们没有HTML注入漏洞,但收到这样能加强我们安全性的报告很好,所以我们给了他1500美元的赏金。
为什么会发生这种情况?
form-action指令在CSP第2版中指定。不幸的是,default-src不涵盖表单操作。这意味着如果您忽略此指令,您的CSP将容易受到表单劫持攻击,这正是Infosec Mastodon甚至我们自己网站发生的情况。因此,本文旨在提高对这个问题的认识,希望能加强许多CSP配置。
扫描您的CSP
我们最近在Burp中发布了一些新的CSP问题被动扫描检查。这些检查将发现诸如表单劫持、白名单资源、不受信任的脚本执行、不受信任的样式执行、格式错误语法、点击劫持和未强制执行的CSP等问题。我将逐一介绍,以便您在遇到这些问题时了解如何修复。
表单劫持
如果您的站点不使用表单操作(在现代应用中很常见),您可以使用’none’关键字指定指令,这是最安全的配置,因为攻击者将无法将表单发布到外部位置。如果您的站点需要"同站点"表单操作,则可以使用’self’关键字。最后,如果您想允许外部位置,可以指定URL,但请注意,如果攻击者发现HTML注入漏洞,他们也能向该位置发布数据。以下是每种配置的示例:
|
|
白名单资源
使用白名单URL是不良实践,因为它们可用于脚本小工具。此扫描检查将查看脚本指令,检查是否有任何域被加入白名单。要修复此问题,建议使用安全随机nonce来保护您的脚本:
|
|
不受信任的脚本执行
此问题指出当您在脚本指令中使用’unsafe-inline’时。顾名思义,这会为您的策略打开跨站脚本攻击的大门,因为您可以注入内联脚本标签。它还包括策略允许通配符域、data: URL、unsafe-eval和弱nonce随机化的情况。安全随机nonce是解决此问题的最佳方法:
|
|
不受信任的样式执行
如果页面上有敏感信息或令牌,基于样式的注入通常会产生重大影响。此问题指出如果您在基于样式的指令中使用’unsafe-inline’。任何通配符域、data: URL和弱nonce随机化也将被报告。要修复此问题,再次在样式指令中使用nonce:
|
|
格式错误语法
当CSP遇到一些格式错误的语法时,它会忽略该值甚至整个指令。此扫描检查查找格式错误的CSP语法,并报告任何不符合规范的指令或值。我们对大量站点进行了扫描,发现了许多常见错误,此扫描检查将帮助消除这些错误。当发现某些无效语法时,指令或值将在问题详细信息中显示。要修复此问题,您应查阅CSP规范并确保语法正确。
点击劫持
此检查将检查CSP中的X-Frame-Options和frame-ancestors指令,并告知您的应用程序是否允许被框架。X-Frame-Options现已弃用,因此我们建议您使用frame-ancestors指令来缓解点击劫持攻击:
|
|
未强制执行的CSP
如果您的策略处于仅报告模式,Burp也会通知您,这意味着策略不会被强制执行但会记录结果。这通常用于过渡到强制策略,但经常会被错误地忽略。如果CSP不存在,它还会按站点报告问题,以鼓励开发人员部署一个。
实际应用
在测试Burp时,我们扫描了我们的漏洞赏金管道,发现了开发人员在部署CSP时犯的许多常见错误。我们将在下面重点介绍其中一些,以帮助您避免它们。
错误协议
一些网站在部署时经常忘记冒号:
|
|
应该是:
|
|
您当然应该避免这样做,因为如果目标站点容易受到XSS攻击,攻击者将能够从任何具有TLS的域注入脚本资源。
缺少分号
忘记包含分号很常见。这可能导致指令名称被用作值,这意味着策略不会强制执行此指令!
这是不正确的:
|
|
应该是:
|
|
错误值
在CSP中,所有特殊指令值都加引号。经常看到值不加引号,以及如下非法值:
|
|
frame-ancestors指令值中没有DENY值。应该是:
|
|
未加引号的哈希或nonce
许多站点也忘记在哈希或nonce周围包含引号。我认为这很常见,因为传统上特殊值加引号而非关键字不加。所以他们感到困惑是可以理解的:
这是不正确的:
|
|
应该是:
|
|
Burp发布
我们希望这篇文章能提高对表单劫持和常见CSP错误的认识。如果您想扫描自己的站点以查找这些问题,可以在早期采用者频道获取Burp。祝狩猎愉快!