Content-Security-Policy(CSP):它是什么,以及如何添加
Content-Security-Policy(CSP)是一个 HTTP 响应头,它告诉浏览器允许从哪些来源加载和执行脚本、样式及其他内容。一个好的 CSP 是抵御跨站脚本(XSS)最强的防线之一。
这是什么
CSP 是一份由浏览器强制执行的允许列表。当你的服务器发送 Content-Security-Policy 响应头时,浏览器会拒绝加载或执行任何策略未明确允许的内容——内联脚本、第三方域名、eval() 等等。
一条策略由一串指令组成。例如,script-src 'self' 的意思是「只运行来自我自己源的 JavaScript」,而 object-src 'none' 则完全阻止旧式插件。
为什么重要
没有 CSP,任何 HTML 注入或 XSS 漏洞都能让攻击者在你用户的浏览器中运行任意 JavaScript——窃取会话、篡改页面或外泄数据。
过弱的 CSP 几乎和没有一样。'unsafe-inline' 会重新放行攻击者依赖的内联脚本,而像 script-src * 这样的通配符源允许脚本从任意位置加载,让 CSP 失去意义。
如何修复
在 next.config.js 中设置该响应头,使其应用于每个响应。先从严格开始,只在需要处放宽。
// next.config.js
const csp = [
"default-src 'self'",
"script-src 'self'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data:",
"base-uri 'none'",
"frame-ancestors 'none'",
"object-src 'none'",
].join("; ");
module.exports = {
async headers() {
return [{ source: "/:path*", headers: [{ key: "Content-Security-Policy", value: csp }] }];
},
};如果你需要内联脚本,请生成每次请求的 nonce,并把它同时加到 script 标签和策略中(script-src 'self' 'nonce-<value>'),而不是使用 'unsafe-inline'。
base-uri 'none'、frame-ancestors 'none' 和 object-src 'none' 可堵住常见的绕过手段(base 标签注入、点击劫持和插件嵌入),对大多数应用来说都是安全的默认值。
常见问题
CSP 会拖慢我的网站吗?
不会。CSP 只是一个由浏览器评估的响应头,不会带来可测量的延迟。真正的成本在于移除内联脚本的工程工作。
Content-Security-Policy 和 X-Frame-Options 有什么区别?
X-Frame-Options 只控制页面嵌入(点击劫持)。CSP 的 frame-ancestors 指令会取代它,而且 CSP 还管控脚本、样式、图片等更多内容。