文章目录
- [一 CSP(内容安全策略)](#一 CSP(内容安全策略))
- [二 CSP基础:如何实现内容安全策略](#二 CSP基础:如何实现内容安全策略)
-
- [2.1 主要实现方式](#2.1 主要实现方式)
- [2.2 基本指令解析](#2.2 基本指令解析)
- [三 简单到复杂:CSP策略示例](#三 简单到复杂:CSP策略示例)
-
- [3.1 示例1:最基本的CSP策略](#3.1 示例1:最基本的CSP策略)
- [3.2 示例2:允许特定CDN资源](#3.2 示例2:允许特定CDN资源)
- [3.3 示例3:更复杂的策略](#3.3 示例3:更复杂的策略)
- [四 CSP进阶概念](#四 CSP进阶概念)
-
- [4.1 非ce与哈希值](#4.1 非ce与哈希值)
- [4.2 报告机制](#4.2 报告机制)
- [五 CSP案例](#五 CSP案例)
-
- [5.1 案例1:防止XSS攻击](#5.1 案例1:防止XSS攻击)
- [5.2 案例2:第三方集成](#5.2 案例2:第三方集成)
- [5.3 案例3:渐进式采用CSP](#5.3 案例3:渐进式采用CSP)
- [六 CSP的局限性](#六 CSP的局限性)
- [七 总结](#七 总结)
一 CSP(内容安全策略)
- 内容安全策略(Content Security Policy,简称CSP)是一种重要的安全层,用于检测和减轻某些类型的前端攻击,包括跨站脚本(XSS)和数据注入攻击。它通过允许开发者创建可信内容来源的白名单,使浏览器只执行或渲染来自这些来源的资源。
在传统的前端开发中,浏览器会无条件地加载和执行任何来自页面内容的资源,这带来了严重的安全隐患:
- XSS攻击:恶意脚本被注入到网页中并在用户浏览器中执行
- 数据泄露:敏感数据被发送到恶意服务器
- 资源劫持:页面加载了被篡改的第三方资源
- CSP像是为你的网站配备了一位严格的保安,只允许预先批准的"访客"(资源)进入。
二 CSP基础:如何实现内容安全策略
2.1 主要实现方式
-
HTTP响应头 (推荐方式):
httpContent-Security-Policy: default-src 'self'
-
HTML meta标签 :
html<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
- HTTP响应头中定义的CSP策略会完全覆盖meta标签中的策略。服务器发送的HTTP头在HTML文档开始解析前就已经被浏览器处理,CSP规范明确指出HTTP头是主要实施方式。
2.2 基本指令解析
CSP通过一系列指令来控制不同类型的资源:
default-src
:默认策略,适用于未明确指定的大多数资源类型script-src
:控制JavaScript的来源style-src
:控制CSS样式表的来源img-src
:控制图片资源的来源connect-src
:控制XMLHttpRequest、WebSocket等连接的来源font-src
:控制网页字体的来源object-src
:控制<object>
、<embed>
和<applet>
等插件media-src
:控制<audio>
和<video>
的来源frame-src
:控制iframe的来源(已废弃,改用child-src
或frame-src
)
三 简单到复杂:CSP策略示例
3.1 示例1:最基本的CSP策略
- 只允许加载同源的资源:
http
Content-Security-Policy: default-src 'self'
这个策略表示:
- 所有JavaScript、CSS、图片、字体等资源必须来自当前网站的域名
- 不允许内联脚本和样式
- 不允许eval()等动态代码执行
3.2 示例2:允许特定CDN资源
- 允许来自自己域名和特定CDN的资源:
http
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.example.com;
style-src 'self' https://cdn.example.com;
img-src 'self' https://images.example.com;
font-src 'self' https://fonts.example.com;
3.3 示例3:更复杂的策略
- 一个电商网站可能需要更复杂的策略:
http
Content-Security-Policy:
default-src 'none';
script-src 'self' https://ajax.googleapis.com https://cdnjs.cloudflare.com 'unsafe-inline' 'unsafe-eval';
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
img-src 'self' https://*.amazonaws.com data:;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://api.example.com;
frame-src 'self' https://checkout.stripe.com;
media-src 'self' https://videos.example.com;
object-src 'none';
四 CSP进阶概念
4.1 非ce与哈希值
- 为了在保持安全性的同时允许特定的内联脚本或样式,CSP提供了两种机制:
-
nonce(一次性数字) :
html<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa"> // 只有nonce匹配的脚本才会执行 </script>
-
对应的CSP头:
httpContent-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
-
哈希值 :
计算脚本内容的SHA256哈希:javascript// 假设脚本内容是:alert('Hello, world.'); // 计算其SHA256哈希得到:qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=
对应的CSP头:
httpContent-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='
4.2 报告机制
- CSP提供了报告功能,可以收集策略违规行为而不实际阻止它们:
-
仅报告模式 (使用
Content-Security-Policy-Report-Only
头):httpContent-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint
-
强制执行+报告模式 :
httpContent-Security-Policy: default-src 'self'; report-uri /csp-report-endpoint
报告端点会收到类似以下的JSON数据:
json
{
"csp-report": {
"document-uri": "https://example.com/page.html",
"referrer": "https://example.com/",
"violated-directive": "script-src 'self'",
"effective-directive": "script-src",
"original-policy": "script-src 'self'; report-uri /csp-report-endpoint",
"disposition": "enforce",
"blocked-uri": "https://malicious.example.com/malicious.js",
"line-number": 10,
"column-number": 20,
"source-file": "https://example.com/page.html",
"status-code": 200,
"script-sample": "alert('XSS Attack!');"
}
}
五 CSP案例
5.1 案例1:防止XSS攻击
问题场景:一个博客网站允许用户评论,但没有适当过滤输入,导致攻击者可以注入:
html
<script>stealCookies();</script>
CSP解决方案:
http
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
- 即使攻击者成功注入了恶意脚本,由于CSP禁止内联脚本执行,攻击将失败。
5.2 案例2:第三方集成
问题场景 :
一个电商网站需要集成:Stripe支付iframe、Google Analytics、来自CDN的jQuery和Bootstrap
CSP解决方案:
http
Content-Security-Policy:
default-src 'self';
script-src 'self' https://ajax.googleapis.com https://cdnjs.cloudflare.com 'unsafe-eval';
style-src 'self' https://cdnjs.cloudflare.com 'unsafe-inline';
img-src 'self' https://*.stripe.com data:;
connect-src 'self' https://api.stripe.com https://www.google-analytics.com;
frame-src 'self' https://checkout.stripe.com;
5.3 案例3:渐进式采用CSP
- 对于已有的大型网站,直接实施严格的CSP可能会破坏现有功能。可以采用渐进式方法:
-
首先使用报告模式 :
httpContent-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint
-
分析报告并调整策略 :
- 识别哪些资源被阻止
- 确定这些资源是否必要
- 将合法的来源添加到白名单
-
逐步实施更严格的策略 :
httpContent-Security-Policy: default-src 'none'; script-src 'self' 'nonce-{random}' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-src 'none'; report-uri /csp-report-endpoint
六 CSP的局限性
虽然CSP是强大的安全工具,但也有其局限性:
- 浏览器兼容性:虽然现代浏览器都支持CSP,但实现细节可能有所不同
- 配置复杂性:对于大型网站,制定和维护CSP策略可能很复杂
- 性能影响:浏览器需要解析和执行策略,可能对性能有轻微影响
- 误报问题:过于严格的策略可能阻止合法功能
七 总结
- 内容安全策略是现代Web应用安全的重要组成部分。正确配置CSP,开发者可以显著降低XSS等前端攻击的风险。
- 记住,没有"一刀切"的完美CSP策略,每个应用都需要根据其特定需求和安全考虑来定制策略。通过持续学习和实践,你将能够为你的Web应用构建强大的安全防线。