CSP and Bypass
内容安全策略 (CSP) 是一种 W3C 标准,允许开发人员控制 Web 应用程序中某些类型脚本的资源加载和执行。它旨在提高 Web 应用程序的安全性并保护用户免受 XSS(跨站脚本)攻击。
什么是CSP?
CSP 代表内容安全策略,它定义了网页可以检索和执行哪些资源。另一种理解它的方法是确定哪些脚本、图像和 iframe 可以从不同的在线位置在特定页面上调用或运行。一些例外包括服务器源和脚本端点。HTTP 响应标头或元元素用于实施内容安全策略。
为什么实施 CSP 至关重要?
为了防止跨站脚本(XSS)等攻击,CSP 技术作为内置技术内置于大多数浏览器中。通过使用适当的 CSP,可以比使用 X-Frame-Options 标头更有效地防止点击劫持。因此,您应该使用 CSP 来保护您的网站免受点击劫持攻击。但是,如果您想保护不支持 CSP 的旧版浏览器,可以将其与 X-Frame-Options 标头结合使用。
例如,输入验证可以保护网站免受注入攻击,但攻击者仍然可以制作独特的有效负载来绕过它。因此,CSP 并不代表你的第一道防线,而是代表你的纵深防御。
即使验证检查被绕过,CSP 也会阻止来自非预期来源的脚本执行,从而在很大程度上消除攻击。
CSP 指令
实施 CSP 时,我们必须了解可以使用的不同策略指令。让我们看一下其中的一些。
script-src
: 指定允许的 JavaScript 源。此外,触发脚本执行的内联脚本事件处理程序 (onclick) 和 XSLT 样式表(可扩展样式表语言)也可以加载到元素中。
default-src
: 该指令指定默认情况下如何获取资源。如果 CSP 标头中未包含 fetch 指令,则浏览器将遵循此指令。
child-src
: 该指令指定 Web Worker 和嵌入式框架可以使用哪些资源。
frame-src
: 该指令限制了可以作为框架调用的 URL。
frame-ancestors
: 指令指定可以嵌入该页面的源。它仅适用于非 HTML 资源,不能在标签中使用(用于防止点击劫持攻击)。
img-src
: 这指定了哪些源可用于加载网页上的图像。
object-src
: 此属性定义元素对象、嵌入和小部件允许的源。
base-uri
: 使用此元素,您可以定义要加载的元素所允许的 URL。
upgrade-insecure-requests
: 通过使用此指令,浏览器将被指示重写 URL 方案,以便 HTTP 被 HTTPS 取代。重写旧 URL 对于拥有许多旧 URL 的网站来说是有益的。
sandbox
: 指令在资源周围创建一个沙箱,类似于 sandbox 属性。使用后的情况,弹出窗口被阻止,插件和脚本被禁止,并且同源策略被强制执行。
其他一些 CSP 指令包括:prefetch-src、connect-src、form-action 等。
CSP 指令的值
*
: Except for data: blob: filesystem schemes, any URL can be used.none
: 在这种情况下不允许加载任何源。self
: 定义允许加载来自同一域的资源的源。data
: 使用数据方案加载资源(例如 Base64 编码图像)unsafe-eval
: 这允许您使用 eval() 和 window.execScript 从字符串创建代码。该来源不应包含在任何指令中。这就是为什么它被称为不安全。unsafe-hashes
: Use this to enable specific event handlers inline.unsafe-inline
: 这允许使用内联资源,例如内联元素、javascript: URL 和内联事件处理程序。出于安全原因,不建议这样做。nonce
: 使用加密随机数(使用一次的数字)的内联脚本白名单。随机数值必须是唯一的,并且是在服务器每次传输策略时生成的。sha256-<hash>
: 该脚本必须具有特定的 SHA256 哈希值才能列入白名单。
要验证应用程序的 CSP,请查看 Google 的 CSP Evaluator。
不安全的规则
Wildcard(*)
CSP Header
1 |
|
XSS payloads:
1 |
|
Unsafe eval()
CSP Header
1 |
|
尽管将脚本源设置为 https://www.cobalt.io,但由于使用了 unsafe-eval,此策略仍然容易受到攻击。
XSS payloads:
1 |
|
Unsafe inline
CSP Header
1 |
|
尽管此策略需要来自 Cobalt.io 站点的脚本,但它很容易受到攻击,因为该指令使用了 unsafe-inline。
XSS payloads:
1 |
|
例子:
请注意,如果实现了 unsafe-inline,则普通的 <tag eventhandler=js>
将起作用。
在这里我们可以看到上面的CSP header 已经实现了。
利用上面提到的payload,我们可以实现XSS漏洞。
JSONP回调并将第三方列入白名单
在 JSONP 中,同源策略 (SOP) 被绕过,因此您可以从服务器请求和检索数据,而不必担心跨域问题。
JavaScript 有效负载可以通过称为“回调”的 GET 参数注入 JSONP 端点,并且端点将以 JSON 形式将它们返回给您,绕过 SOP(同源策略)。例如,我们可以通过 JSONP 端点发送 JavaScript 有效负载。下面是一个例子:
https://accounts.google.com/o/oauth2/revoke?callback=alert(1)
如果标头将这些端点之一列入白名单,则 script-src 策略可能会导致问题。 JSONP 端点允许我们通过加载恶意 JavaScript 来绕过 CSP 策略。JSONBee 中有许多现成的CSP绕过的地址。
CSP header
1 |
|
由于accounts.google.com允许加载JavaScript文件,因此将加载以下有效负载。为了加载我们的恶意 JavaScript,我们滥用了 JSONP 功能。
XSS payloads
1 |
|
缺少 object-src 和 default-src
CSP header
1 |
|
1 |
|
XSS payloads
1 |
|
Angular JS
如果 AngularJS 应用程序从白名单域加载任何脚本,则可以绕过 CSP 策略。为此,回调函数和有漏洞的部分是一定会被调用的。另外,为 AngularJS
事件定义了一个特殊的 $event
对象,它简单地引用浏览器事件对象。通过这个对象,可以绕过CSP。
CSP header
1 |
|
XSS payloads:
1 |
|
1 |
|
文件上传
如果您可以上传 JS 文件,则可以绕过 CSP。服务器很有可能对上传的文件进行验证,只允许上传指定的文件类型。
此外,即使您将 JS 代码上传到服务器接受的扩展名的文件中(例如 script.js)。这还不够,因为某些服务器(例如 apache 服务器)根据文件的扩展名确定文件的 MIME 类型。例如,Chrome 浏览器会拒绝在图像中运行的 Javascript 代码。
CSP header
1 |
|
XSS payloads:
1 |
|
白名单方案
CSP header
1 |
|
XSS payloads:
1 |
|
在这里我们可以注意到上面的 CSP 标头已实现。
提交上述payload后,我们就可以实现XSS,绕过CSP。
绕过base-uri
如果定义的 CSP 中不存在 base-uri 指令,则可以执行悬空标记注入。如果脚本具有相对路径(如 /js/app.js),则可以通过使页面从服务器加载脚本来滥用基本标签来获取 XSS。如果通过 HTTPS 加载易受攻击的页面,则应使用 HTTPS URL。
CSP header
1 |
|
XSS payloads:
1 |
|
我们可以注意到 CSP 标头的实现方式就像我们上面讨论的那样。
提交上述payload后,我们得到xss,
文件夹路径绕过
当您使用 %2f
将“/
”编码为 CSP 策略的一部分并将其指向文件夹时,它仍将被视为该文件夹的一部分。几乎所有现代浏览器似乎都是这种情况。
当服务器对其进行解码时,可以使用“%2f..%2f
”来绕过它,从而绕过文件夹限制。例如,您可以访问http://example.com/company/
,执行http://example.com/company%2f..%2fatttacker/file.js
将绕过限制。
CSP header:
1 |
|
XSS payloads:
1 |
|
通过IFrame绕过CSP
攻击者可以使用 Iframe 绕过以下 CSP 策略。应用程序必须允许来自白名单域的 iframe 才能执行绕过。使用 iframe
的 srcdoc 属性可以轻松进行 XSS 攻击。
CSP header
1 |
|
XSS payloads:
1 |
|
CSP注入绕过
在这种情况下,用户的输入会反映在 CSP 标头中。我们以下面的 URL 为例:
https://www.cobalt.io?param=payload.
如果您的输入反映在 CSP 标头中,您应该看到以下内容。
CSP header
1 |
|
因此 script-src 可以设置为我们想要的任何值。该值可以轻松设置为我们控制的域,绕过 CSP。
CSP 数据泄露
尽管严格的 CSP 禁止您与外部服务器交互,但无论 CSP 多么严格,您仍然可以采取一些措施来窃取数据。
Location
为了将秘密信息发送到攻击者的服务器,您可以简单地更新位置:
1 |
|
总结
CSP 是针对 XSS 和点击劫持攻击的深度防御策略。然而,如果实施不当,CSP 很容易被绕过。因此,所有脚本最好都驻留在您的主机上,并且您的 CSP 不应允许来自 Internet 的任何内容。
我们希望您喜欢这篇博文。在我们的下一篇博文中再次见到您。