一、什么是CSP
内容安全策略(Content Security Policy)是一种浏览器安全机制,通过白名单的方式控制页面可以加载和执行的资源,有效防御XSS、数据注入等攻击。
1.1 CSP的核心功能
- 限制JavaScript、CSS、图片等资源的来源
- 禁止内联脚本和eval()的使用
- 控制表单提交目标
- 防止点击劫持
二、CSP指令详解
2.1 基础指令
<!-- 最严格的CSP策略 -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
frame-ancestors 'none'">
2.2 常用指令说明
// default-src: 默认策略,其他未指定的资源类型都使用此策略
// script-src: JavaScript来源
// style-src: CSS来源
// img-src: 图片来源
// font-src: 字体来源
// connect-src: XHR、WebSocket、EventSource来源
// frame-src: iframe来源
// frame-ancestors: 允许嵌入的父页面
// form-action: 表单提交目标
// base-uri: <base>标签允许的URL
2.3 使用Nonce
<?php
$nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: script-src 'nonce-$nonce'");
?>
<script nonce="<?php echo $nonce; ?>">
// 只有带正确nonce的脚本才会执行
console.log('允许执行');
</script>
2.4 使用Hash
<!-- 计算脚本的SHA-256 hash -->
<meta http-equiv="Content-Security-Policy"
content="script-src 'sha256-hash值'">
<script>console.log('hello');</script>
三、CSP报告机制
3.1 配置报告端点
header("Content-Security-Policy:
default-src 'self';
report-uri /csp-violation-report;
report-to csp-endpoint");
header("Report-To: {
\"group\": \"csp-endpoint\",
\"max_age\": 10886400,
\"endpoints\": [{\"url\": \"/csp-violation-report\"}]
}");
3.2 处理违规报告
// /csp-violation-report 端点
$data = json_decode(file_get_contents('php://input'), true);
error_log('CSP违规: ' . json_encode($data));
// 报告格式
/*
{
"csp-report": {
"document-uri": "https://example.com/page",
"violated-directive": "script-src 'self'",
"blocked-uri": "https://evil.com/bad.js"
}
}
*/
四、常见场景配置
4.1 静态网站
Content-Security-Policy:
default-src 'self';
img-src 'self' data: https:;
style-src 'self' 'unsafe-inline'
4.2 使用CDN
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.jsdelivr.net;
style-src 'self' https://cdn.jsdelivr.net;
4.3 单页应用(SPA)
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-{随机值}';
connect-src 'self' https://api.example.com;
style-src 'self' 'nonce-{随机值}'
最佳实践
1. 从Report-Only模式开始测试
2. 使用nonce或hash代替unsafe-inline
3. 避免使用unsafe-eval
4. 定期审查CSP报告
5. 逐步收紧策略
五、调试工具
- Chrome DevTools: Console查看CSP错误
- CSP Evaluator: Google提供的在线检测工具
- Report URI: CSP报告收集服务
总结
CSP是防御XSS的重要防线,合理配置可以大幅提升安全性。记住从严格策略开始,配合报告机制逐步优化。