避免 xss 99% 的都晓得要做标签过滤,和标签属性过滤,50% 晓得非标签内容本义,40% 晓得 httponly,10% 的人晓得 waf,只有 1% 的人晓得它。
周末尝试用跑路技巧来强行引出 CSP,故事有点牵强,本想大家都一起留言说如何解决这种 self-xss 的问题,然而成果不是很好,这里我本人回应下吧~~
对于这种”固执型“存储内容,存在更高权限的用户编辑其他人低权限用户的内容的状况。上面这个计划应该能在肯定水平上解决问题。
当然 csp 和 httponly 的指定也都是服务端输入的。waf 是一层能够帮忙咱们拦挡掉一些攻打代码的网络防火墙,属于云产品领域,大家能够自行搜寻相干云产品。
明天次要和大家分享学习下 CSP(Content Security Policy)的常识,CSP 里定义的内容有很多,不仅能够避免被 XSS 还有被 iframe 或者 iframe 援用等
如果咱们提供的是一个存储型的服务,比方博客。
案例 http://mengkang.net/demo/csp/…
<html>
<header>
<title></title>
</header>
<body>
<div id="blog">
<script>
alert(document.cookie);
</script>
</div>
</body>
</html>
也就是说 ”#blog” 外面的内容是不可信的,一方面要做好展现时的过滤,如果咱们没做好过滤,下面的 js 就会执行;另一方面,咱们也不能随便批改用户的内容,所以即便展现时过滤了,而原始内容不能批改,当编辑用户的内容时,仍然会触发xss
,也就是self-xss
,这次要攻打的就是有编辑其他人内容的人。
CSP 次要是为了解决跨站脚本攻打和数据注入攻打,它的外围原理是在服务端渲染页面的时候 http header 头里带上 CSP 协定,协定外面有一个nonce
(服务端随机生成的码,不须要存储),而后页面须要执行的 js 必须也必须带上该nonce
。
拦挡攻打
案例 http://mengkang.net/demo/csp/…
<?php
$nonce = md5(uniqid());
$policy = "script-src'nonce-". $nonce ."';";
header("content-security-policy:". $policy);
?>
<html>
<header>
<title></title>
</header>
<body>
<div id="blog">
<script>
alert(document.cookie);
</script>
</div>
</body>
</html>
这样,用户写的博客外面的 js 就不会被执行了。并且管制台上会有报错记录
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src'nonce-be6737d35f2c558943dae9ad44c369ee'". Either the'unsafe-inline'keyword, a hash ('sha256-0FWdMKk2PWuytGHwpB/r+HwqVTWZoSWX/M+OKSueWHI='), or a nonce ('nonce-...') is required to enable inline execution.
然而如果页面有一些咱们本人开发的 js 要执行怎么办?
外部引入 js 的放行
案例 http://mengkang.net/demo/csp/…
<?php
$nonce = md5(uniqid());
$policy = "script-src'nonce-". $nonce ."';";
header("content-security-policy:". $policy);
?>
<html>
<header>
<title></title>
</header>
<body>
<div id="blog">
<script>
alert(document.cookie);
</script>
</div>
<div id="notice">
<script nonce="<?php echo $nonce?>">
alert("我是本人人,别拦挡");
</script>
</div>
</body>
</html>
原理就是咱们本人的 js script 标签上加上了服务端渲染的
nonce
值,所以能失常执行;而攻击者写的博客外面的 js 是写死的,即便他写了一个nonce
,然而他没法管制“被攻击者”关上页面时的nonce
值正好等于他写死的那个值。
内部引入 js 的放行
案例 http://mengkang.net/demo/csp/…
<?php
$nonce = md5(uniqid());
$policy = "script-src'nonce-". $nonce ."';";
header("content-security-policy:". $policy);
?>
<html>
<header>
<title></title>
</header>
<body>
<div id="blog">
<script>
alert(document.cookie);
</script>
</div>
<div id="notice">
<script nonce="<?php echo $nonce?>">
alert("我是本人人,别拦挡");
</script>
</div>
<script src="test.js"></script>
</body>
</html>
test.js
是不能被引入的,须要革新成
<script src="test.js" nonce="<?php echo $nonce?>"></script>
如果内部引入 js 有动静插入的状况 ,肯定要把 nonce 传递给内部 js。比方test.js
背地是一段服务端代码,外面会执行document.write
,解决方案是
<script src="test.js?nonce=<?php echo $nonce?>" nonce="<?php echo $nonce?>"></script>
test.js
在收到参数 nonce 之后,对前面动静插入的 js 做相似下面的操作两类操作增加nonce
行内 js 革新
如果页面中有大量的行内 js,须要革新成外部引入 js 的形式
<span onclick="alert(1);"></span>
这样的 js 是不能被执行的,须要革新成
<span id="myButton"></span>
<script nonce="<?php echo $nonce?>">
document.getElementById("myButton").addEventListener("click", myFunction);
function myFunction(){alert(1);
}
</script>
最终版
加上各种浏览器的兼容性,还有 CSP1 和 CSP2 的兼容性之后失去以下通过实战我的项目的规定
content-security-policy: base-uri 'self';script-src 'self' 'unsafe-inline' 'unsafe-eval' 'report-sample' https: http: 'strict-dynamic' 'nonce-543c368ef6f944e1a93fa60d39687a02';frame-src 'self' a.baidu.com b.taobao.com ;worker-src blob: 'self' data:;object-src 'self' a.baidu.com;frame-ancestors *.aliyun.com;report-uri /csp/report;
能够参考这个去改下
frame-src
管制咱们能够引入的页面域名frame-ancestors
管制谁能够援用咱们report-uri
是 csp 拦挡日志上报地址
原创码字不易,期待你的关注,我的公众号