内容安全策略:随机数与哈希
使用内联脚本随机数、已知代码片段的哈希以及 report-uri 编写严格的 CSP,以便在生产环境中监控违规行为。
内容安全策略:随机数与哈希 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。
CSP 回顾
CSP 是一个 HTTP 标头,用于规定浏览器允许加载的内容,包括脚本、样式、图片、字体、框架和连接。这是一种纵深防御:即使 XSS 绕过了您的过滤器,CSP 通常也能阻止攻击载荷。
CSP 标头剖析
每条指令都会列出允许的来源。'self' 表示同源。也可以允许特定的 URL。
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
font-src 'self' https://fonts.gstatic.com;
frame-ancestors 'none';
base-uri 'self';常见指令
default-src:所有内容的后备规则。script-src:JavaScript。style-src:CSS。img-src:图片。connect-src:fetch/XHR/WebSocket。font-src:字体。frame-ancestors:哪些站点可以将您的页面嵌入 iframe(点击劫持防护)。
'unsafe-inline'——常见漏洞
许多站点添加 'unsafe-inline',以允许内联 <script> 标签和 onclick 属性。这会破坏 CSP 的主要目的,因为 XSS 攻击载荷可以以内联方式运行。请改用随机数或哈希。
随机数——一次性允许列表
为每个请求生成一个随机随机数。为合法的内联脚本添加该随机数。浏览器只允许带有匹配随机数的脚本运行。
// Server (Express middleware):
import crypto from 'crypto';
app.use((req, res, next) => {
res.locals.nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy',
`script-src 'nonce-${res.locals.nonce}' 'strict-dynamic'`
);
next();
});
// Template:
<script nonce="<%= nonce %>">window.config = {...};</script>'strict-dynamic'
将随机数与 'strict-dynamic' 结合使用:受信任的脚本(带有该随机数的脚本)可以加载其他脚本。这样就不需要列出每个脚本来源 URL。这是当前 CSP 的最佳实践。
哈希——静态允许列表
对于已知且固定的内联脚本(例如,您的构建过程始终生成相同的启动代码片段),请计算其 SHA-256 值,并将其作为哈希来源添加。不需要为每个请求生成随机数。
// Hash of: console.log('hi');
Content-Security-Policy: script-src 'sha256-XwCNuB+/RUgPlAACI+yHrUKqUsm4zlpGV/Q8tEUx0Q4='内联样式哈希
内联 <style> 标签也可以采用相同的技巧:计算其哈希值,并将其添加到 style-src 中。对于 CSS,这比 'unsafe-inline' 更好。
CSP 报告模式
使用 Content-Security-Policy-Report-Only 可以在不强制执行策略的情况下进行测试。违规情况会报告到您的端点,但不会阻止任何内容。这非常适合逐步部署 CSP。
Content-Security-Policy-Report-Only:
default-src 'self';
report-uri /csp-violations
// /csp-violations receives POSTs like:
{
"csp-report": {
"document-uri": "https://example.com/",
"violated-directive": "script-src 'self'",
"blocked-uri": "https://evil.com/x.js"
}
}report-to(现代方式)
report-to + Reporting-Endpoints 是 report-uri 的现代替代方案。数据相同,但结构更清晰。
Reporting-Endpoints: csp="/csp-reports"
Content-Security-Policy: script-src 'self'; report-to csp框架集成
Next.js:通过 middleware.ts 或 next.config.js 标头设置 CSP。Nuxt:使用 nuxt-security 模块。Vite:配置开发服务器标头;生产环境则通过托管平台(Vercel、Netlify)的标头配置进行设置。
// next.config.js
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'strict-dynamic'"
}]
}];
}
};测试 CSP
打开 DevTools → 控制台:CSP 违规情况会记录在那里。使用 https://csp-evaluator.withgoogle.com/ 评估您的策略。先在生产环境中使用仅报告模式,修复所有违规后再强制执行。
快速检查
为什么在 script-src 指令中使用 'unsafe-inline' 会被视为 CSP 弱点?
回顾:CSP 最佳实践
为每种资源类型设置相应指令的 Content-Security-Policy 标头。避免使用 'unsafe-inline',改用随机数 + 'strict-dynamic' 或 SHA 哈希。设置 frame-ancestors 'none'(或 'self')。先在仅报告模式下测试。将违规情况发送到 /csp-violations(或使用现代的 report-to)。各类框架都支持通过中间件或配置标头设置 CSP。
用 AI 导师学习 HTML — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 41
- 课程
- 163
常见问题解答
「内容安全策略:随机数与哈希」课时是免费的吗?
是的 — 「内容安全策略:随机数与哈希」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。
「内容安全策略:随机数与哈希」这节课中我会学到什么?
使用内联脚本随机数、已知代码片段的哈希以及 report-uri 编写严格的 CSP,以便在生产环境中监控违规行为。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Frontend Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「内容安全策略:随机数与哈希」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Frontend Academy 课中编写并运行代码吗?
能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- XSS 防护:输出编码与 CSP
- CSRF:SameSite Cookie 与令牌
- 内容安全策略:随机数与哈希
- 前端 OAuth 流程