什么是内容安全策略(CSP)?
内容安全策略(Content Security Policy,简称CSP)是一种重要的安全机制,它通过HTTP响应头或<meta>
标签来定义哪些资源可以被加载和执行,从而有效减少跨站脚本攻击(XSS)等安全威胁。CSP是现代Web应用中保护JavaScript代码安全的关键防线。
为什么需要CSP?
- 防止XSS攻击:通过限制脚本来源,阻止恶意脚本注入
- 控制资源加载:精确控制哪些外部资源可以被加载
- 报告违规行为:收集潜在的安全威胁信息
- 减少攻击面:限制不必要的资源加载和执行
基本CSP配置
最简单的CSP配置可以通过HTTP响应头实现:
http
Content-Security-Policy: default-src 'self'
这条策略表示只允许加载同源(same origin)的资源。
常见CSP指令详解
资源限制指令
-
default-src:为其他指令提供默认值
-
script-src:控制JavaScript脚本的来源
'self'
:只允许同源脚本'unsafe-inline'
:允许内联脚本(不推荐)'unsafe-eval'
:允许eval()等动态代码执行(不推荐)- 特定域名:如
https://cdn.example.com
-
style-src:控制CSS样式表的来源
-
img-src:控制图片资源的来源
-
connect-src:限制XMLHttpRequest、WebSocket等连接的来源
-
font-src:控制字体文件的来源
-
object-src:控制
<object>
、<embed>
、<applet>
等标签的来源 -
media-src:控制
<audio>
、<video>
等媒体资源的来源 -
frame-src:控制
<iframe>
、<frame>
等框架的来源
特殊指令
- base-uri:限制
<base>
标签的URL - form-action:限制表单提交的目标URL
- frame-ancestors:限制哪些页面可以嵌入当前页面(替代X-Frame-Options)
- report-uri / report-to:指定违规报告发送的URL
实际配置示例
严格策略(推荐)
http
Content-Security-Policy:
default-src 'none';
script-src 'self' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
form-action 'self';
base-uri 'self';
frame-ancestors 'none';
report-uri /csp-report-endpoint
渐进式策略(适用于遗留系统)
http
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
report-uri /csp-report-endpoint
CSP与JavaScript最佳实践
-
避免内联脚本:将所有JavaScript代码移到外部文件
-
使用nonce或hash:安全地允许特定内联脚本
- Nonce示例:
html
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa"> // 内联脚本 </script>
httpContent-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
- Nonce示例:
-
限制第三方脚本:明确列出允许的CDN域名
-
禁用eval():除非绝对必要,否则避免使用
eval()
、new Function()
等 -
实施报告机制:先使用
Content-Security-Policy-Report-Only
模式测试策略
调试与部署策略
-
使用Report-Only模式:部署前先监控潜在问题
httpContent-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint
-
分析违规报告:根据实际访问情况调整策略
-
逐步收紧策略:从宽松开始,逐步限制
-
测试所有功能:确保合法功能不受影响
常见问题与解决方案
- 第三方小工具问题:为每个第三方服务明确添加允许的域名
- 内联事件处理程序:重写为事件监听器或使用nonce
- 动态样式问题:使用CSS类代替内联样式,或添加
'unsafe-inline'
- 浏览器扩展干扰:考虑是否需要在策略中为常见扩展添加例外
结论
内容安全策略是JavaScript安全的重要防线,正确配置CSP可以显著提高Web应用的安全性。虽然初始配置可能需要一些调整,但长期来看,它能有效减少XSS等攻击的风险。建议开发团队将CSP作为Web应用安全策略的核心组成部分,并定期审查和更新策略以适应应用的变化。
记住,最严格的安全策略是平衡安全性和功能性的结果。始终从实际应用需求出发,构建既安全又实用的内容安全策略。