一、了解CSP内容安全策略
CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。
作用就是:大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。有两种方法可以启用CSP
1、方法一:是通过 HTTP 响应头信息的Content-Security-Policy的字段
Content-Security-Policy: script-src 'self; object-src 'none'; style-src cdn.example.orgthird-party.org;child-src https:
在PHP中直接使用 header() 函数定义响应头内容即可。
2、方法二:通过网页的meta标签
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
一旦启用后,不符合的CSP外部资源就会被组织加载
二、实验场景
1、需要两台web服务器来实现跨站的效果。
构建第一个界面,是用于发送报告的也就是检测的界面,也是我们要检测的页面 myweb.php(114.165)
<?php
header("Content-Security-Policy: script-src 'self' ; report-uri http://192.168.114.96/web_repot/report.php")
#script-src:定义针对所有类型(js/image/css/font/ajax/iframe/多媒体等)资源的默认加载策略。 7主机
#script-src 'self' http://www.woniunote.com,对于脚本: 只信任当前域名自己和http://www.woniunote.com
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>受保护页面</title>
</head>
<body onload='localtion.href="http://192.168.114.96/a.js"'>
<p>我可以跳转到js</p>
</body>
</html>
- 当访问这个页面的时候,会自动引用一个 a.js 的外部文件这个a.js也是部署在114.96检测服务器上。
- 请求头会发现页面在访问外部文件,通过这端代码来向我们的114.96检测服务器发送报错信息。report-uri http://192.168.114.96/web_repot/report.php"
2、在检测web服务器上需要个文件
- report.php #用来接受检测页面发送过来的请求,并存进数据库
- db.php #数据库语句代码
- show.php #显示界面,动态读取存储信息,并显示在界面中
3、脚本代码
- db.php
<?php //DML:插入 function DML($mysql,$ip='127.0.0.1',$mysql_uname='root',$passwd='',$databas='report',$port=3306){ $con=mysqli_connect($ip,$mysql_uname,$passwd,$databas,$port); //建立链接 mysqli_query($con, "set names utf8"); //中文乱码转意 $res=mysqli_query($con,$mysql); if($res){ mysqli_commit($con); mysqli_close($con); return 1; }else{ mysqli_close($con); return 0; } } #查询 function DQL($mysql,$ip='127.0.0.1',$mysql_uname='root',$passwd='',$databas='report',$port=3306){ $con=mysqli_connect($ip,$mysql_uname,$passwd,$databas,$port); //建立链接 mysqli_query($con, "set names utf8"); //中文乱码转意 $res = mysqli_query($con,$mysql); $rows = mysqli_fetch_all($res,MYSQLI_ASSOC); return $rows; } $sql="select * from csp_report order by id;"; $res=DQL($sql); echo json_encode($res); ?>
- show.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- <meta http-equiv="refresh" content="2"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript" src="/jquery-3.4.1.min.js"></script> <title>显示界面</title> </head> <style> table{ border: 3px solid rgb(0, 0, 0); } td{ width: 100px; border: 3px solid rgb(0, 0, 0); } </style> <script> function myrefresh() { window.location.reload(); } setTimeout('myrefresh()',2000); function onLoad(){ $.get('db.php',function(data){ $('#out').empty(content) //清空 var dt=eval(data); var content="" content+="<tr>" content+="<td>ID</td>" content+="<td>时间</td>" content+="<td>blocked-uri</td>" content+="<td>document-uri</td>" content+="<td>original-policy</td>" content+="<td>source-file</td>" content+="<td>violated-directive</td>" content+="</tr>" content+="<tr>" dt.forEach(res=>{ content+="<td>"+res['id']+"</td>" content+="<td>"+res['rt_time']+"</td>" content+="<td>"+res['bd_uri']+"</td>" content+="<td>"+res['dt_uri']+"</td>" content+="<td>"+res['ol_policy']+"</td>" content+="<td>"+res['se_file']+"</td>" content+="<td>"+res['vd_dir']+"</td>" content+="</tr>" });$('#out').append(content); }) } </script> <body onload="onLoad()"> <button onclick="onLoad()">点我</button></br> <table id="out"> </table> </div> </body> </html>
- report.php
<?php #接收的脚本在虚拟机dvwa/cs/myweb.php include './db.php'; $time = date('Y-m-d H:i:s'); $data = file_get_contents('php://input'); // 利用伪协议取得请求内容 $json = json_decode($data, true); // 生成关联数组 $bluri=$json['csp-report']['blocked-uri']; $douri=$json['csp-report']['document-uri']; $origin=$json['csp-report']['original-policy']; $source=$json['csp-report']['source-file']; $viola=$json['csp-report']['violated-directive']; $sql="INSERT INTO csp_report (rt_time,bd_uri,dt_uri,ol_policy,se_file,vd_dir)value('$time','$bluri','$douri','$origin','$source','$viola')"; DML($sql) ; #数据插入 ?>