网站内容安全策略CSP配置部署实战指南

一、什么是内容安全策略CSP

内容安全策略CSP是一种浏览器安全机制,通过HTTP响应头告诉浏览器允许加载哪些来源的资源。当页面试图加载不在白名单中的资源时,浏览器会直接阻止并生成违规报告。CSP可有效防御XSS攻击、数据注入、点击劫持等多种前端安全威胁。

CSP通过Content-Security-Policy响应头实现。配置格式为一系列指令和值的组合,每个指令控制一类资源的加载策略。推荐先从Content-Security-Policy-Report-Only模式开始,该模式下浏览器只报告违规行为而不实际阻止,适合在测试阶段验证策略正确性。

二、CSP常用指令与配置语法

CSP指令覆盖了Web页面的各类加载资源。script-src控制JavaScript脚本的来源,是最关键的指令,建议设置为严格来源如nonce或hash方式而非域名白名单。style-src控制CSS样式的加载来源。img-src控制图片来源。connect-src控制XMLHttpRequest和Fetch等网络请求的来源。frame-src控制iframe的嵌入来源。object-src建议设置为none以禁用插件加载。

每个指令的值可以是一个或多个来源表达式:自关键字指定当前域名来源,特定域名如trusted-cdn.example.com允许该域名下的资源,https指定仅允许HTTPS来源,none表示完全禁止,unsafe-inline允许内联代码但不推荐使用。

三、基于nonce的严格CSP配置

传统的域名白名单CSP已被证实不够安全,推荐采用基于nonce或hash的严格CSP。nonce是每次HTTP响应时服务器生成的一次性随机值,服务器在响应头中将nonce值加入script-src指令,同时内联脚本的script标签上需添加相同的nonce属性。浏览器会比对两处nonce值是否一致。

这种方案的优势在于只有服务器颁发过nonce的脚本才能执行,攻击者注入的脚本由于不知道nonce值会被浏览器阻止。配合哈希校验使用效果更佳,对于静态脚本可预先计算其哈希值加入CSP策略中。

四、CSP违规报告机制

CSP强大的地方在于它不仅能防御攻击,还能记录和报告攻击行为。通过report-uri或report-to指令配置报告接收端点,当浏览器阻止违规资源时会向指定地址发送JSON格式的违规报告。报告中包含被阻止的资源URL、触发的指令、违规页面URL和行号等关键信息。

生产环境下建议搭建专门的CSP报告收集服务或使用第三方服务接收报告。定期分析CSP报告可以发现新的攻击尝试或配置问题,并及时调整策略。需要注意的是报告可能较大,建议对频次和规模施加限制,防止报告收集接口被滥用。

五、CSP部署最佳实践

CSP的部署应该循序渐进。首先在开发环境启用Content-Security-Policy-Report-Only模式收集所有违规报告,根据报告调整策略直至无预期外的违规。然后将策略切换到强制模式并继续监控报告,定期审查和更新策略以适配业务变化。

部署过程中注意不要使用unsafe-inline和unsafe-eval,这两项会大幅削弱CSP的防护效果。强烈建议配合HTTPS使用,混合内容会在CSP中产生警告。对于第三方资源建议仔细评估其安全性,现代CSP三级规范已支持更细粒度的控制,建议及时跟进浏览器对新特性的支持情况。

相关推荐

延伸阅读

常见问题

找软件开发公司之前,先搞清楚这五个问题

准备找软件开发公司做项目,但不知道从哪开始沟通?别上来就问价格,先搞清楚这五个问题。问对了,沟通效率高、报价也更有参考价值。

2026-07-24
技术博客

别再往localStorage里塞token了,这些坑你踩过几个

<h2>误区一:localStorage存token,方便就完事了</h2><p>这是前端圈子里流传最广的偷懒写法。新手教程里经常这么教——登录成功后拿到token,顺手localStorage.setItem存起来,下次请求带上就行。看起来没毛病,实际上埋了一颗定时炸弹。</p><p>不少已经上线跑了一两年的项目,至今还在用这种方式管理登录态。开发者觉得又不是银行系统没那么严格,但现实是:只要你的页面存在一个XSS漏洞,攻击者一行document.cookie都不用碰,直接读localStorage就能把token拿走。</p><h2>误区二:我做了输入校验,XSS不会发生在我这里</h2><p>很多团队的安全意识停留在输入框做了过滤就行。但XSS的攻击面远不止表单输入。第三方脚本、富文本编辑器、URL参数拼接、甚至CDN被污染,都可能成为注入点。</p><p>更麻烦的是,现代前端项目依赖大量npm包,供应链攻击已经不是新闻了。某个深层依赖被植入恶意代码,打包后混在你的业务JS里,运行时悄悄把localStorage里的内容发到外部服务器——这种事不是假设,是真实发生过的安全事件。</p><h2>为什么这些做法是错的</h2><p>根本原因在于:localStorage对JavaScript完全开放。任何在当前域下执行的JS代码,不管是你自己写的还是被注入的,都能无条件读写localStorage的全部内容。它没有访问控制,没有过期机制,没有加密,就是一个对脚本透明的键值仓库。</p><p>换句话说,localStorage的设计初衷就不是用来存敏感信息的。它适合存主题偏好、语言设置这类丢了也无所谓的数据。把身份凭证放进去,相当于把家门钥匙挂在门把手上——门锁本身可能很结实,但钥匙谁都能拿。</p><p>而sessionStorage虽然生命周期短一些,关闭标签页就清除,但在XSS面前同样毫无抵抗力,本质问题一模一样。</p><h2>正确做法:httpOnly Cookie方案</h2><p>把token的存储和传输交给httpOnly Cookie。具体操作是:后端在登录接口的响应头里通过Set-Cookie下发token,同时设置httpOnly、Secure、SameSite属性。</p><p>httpOnly的作用很直接——禁止JavaScript读取这个cookie。就算页面被XSS了,攻击者的脚本也拿不到cookie内容。Secure确保只在HTTPS下传输,SameSite限制跨站请求携带,三者组合起来构成基本防线。</p><p>前端这边不需要手动管理token了。浏览器会自动在同域请求里带上cookie,接口该怎么调还怎么调。如果是跨域场景,配合credentials include和后端的CORS白名单即可。</p><h3>补充:短期token加refresh机制</h3><p>access_token设置较短过期时间(比如15分钟),refresh_token放在httpOnly cookie里,过期后静默刷新。这样即使access_token意外泄露,窗口期也非常有限。</p><h2>上线前自查清单</h2><p>以下几项逐条过一遍,没做到的赶紧补:</p><p>1. localStorage和sessionStorage里是否还残留token、密码、用户敏感信息?全部清理掉。</p><p>2. 身份凭证是否已迁移到httpOnly Cookie?确认Set-Cookie响应头包含httpOnly、Secure、SameSite=Strict或Lax。</p><p>3. 前端是否存在innerHTML直接拼接用户输入的写法?逐一排查并替换为textContent或经过转义处理。</p><p>4. 第三方脚本是否使用了integrity属性做子资源完整性校验?没有的话加上SRI hash。</p><p>5. CSP头是否已配置?至少限制script-src为白名单域,杜绝inline脚本执行。</p><p>6. 定期跑一次依赖审计(npm audit),看看有没有已知漏洞的包还在项目里。</p><p>安全这件事没有一劳永逸的方案,但至少别在最基础的地方翻车。把token从localStorage挪出来,是成本最低、收益最明确的一步。</p>

2026-07-24
行业资讯

AI代码助手用了半年,团队的开发效率到底提升了多少

2025年团队全面引入了AI代码辅助工具。半年用下来,有好的变化也有新的问题。这篇是来自一线开发团队的实测数据和使用感受,不吹不黑。

2026-07-24
电话咨询 微信咨询 在线咨询 返回顶部
xycx202108

微信扫码咨询

×