Web 安全响应头配置:Nginx / Next.js

最后更新: 2026-02-26

一、为什么需要安全响应头

HTTP 响应头中的安全策略是浏览器与服务器之间的"约定",告诉浏览器应该如何处理页面内容、限制哪些行为。缺少这些头会被安全扫描工具标记为漏洞,也会在实际攻击中留下可利用的空间。


二、各安全头含义速查

响应头作用可选参数推荐值
X-Content-Type-Options禁止浏览器 MIME 类型嗅探,防止 XSSnosniff(唯一有效值)nosniff
X-XSS-Protection启用旧版浏览器内置 XSS 过滤器0 禁用 / 1 启用 / 1; mode=block 启用并阻断 / 1; report=<url> 启用并上报1; mode=block
X-Frame-Options控制页面是否允许被 iframe 嵌套,防点击劫持DENY 完全禁止 / SAMEORIGIN 仅同域名 / ALLOW-FROM <url> 指定域名(已废弃)SAMEORIGIN
Referrer-Policy控制跨域请求时 Referrer 信息的携带范围no-referrer 不发送 / no-referrer-when-downgrade / origin 仅域名 / origin-when-cross-origin / same-origin 仅同域 / strict-origin / strict-origin-when-cross-origin / unsafe-url 始终完整发送strict-origin-when-cross-origin
X-Permitted-Cross-Domain-Policies禁止 Flash/PDF 等加载跨域策略文件none 完全禁止 / master-only 仅主策略文件 / by-content-type / by-ftp-filename / all 全部允许none
X-Download-Options禁止 IE 直接在浏览器中打开下载文件noopen(唯一有效值)noopen
Content-Security-Policy白名单控制页面可加载的资源来源,最全面的 XSS 防护指令众多,常用:default-src / script-src / style-src / img-src / font-src / frame-src / frame-ancestors / form-action / connect-src / media-src;来源值:'self' / 'none' / 'unsafe-inline' / 'unsafe-eval' / 'nonce-<value>' / <url>default-src 'self' 按需扩展各指令
Permissions-Policy控制页面可使用的浏览器硬件/敏感 API 权限格式:feature=(allowlist);常用功能:camera / microphone / geolocation / payment / usb / fullscreen / accelerometer / gyroscope;allowlist:() 禁用 / (self) 仅同域 / (*) 全部允许 / (<origin>) 指定域名按需禁用,fullscreen=(self)
Cross-Origin-Resource-Policy控制资源是否允许被跨域页面通过标签加载same-origin 仅同域名 / same-site 含子域名 / cross-origin 允许任意跨域(等同不设置)same-originsame-site
Clear-Site-Data清除客户端缓存/Cookie/Storage"cache" / "cookies" / "storage" / "executionContexts" / "*" 全部清除;可组合使用退出登录接口用 "cache", "cookies", "storage"

三、Nginx 配置

将以下内容放入 server {} 块,或提取为独立 include 文件统一管理:

Yaml
1# /etc/nginx/conf.d/security-headers.conf 2 3# 禁止 MIME 类型嗅探 4add_header X-Content-Type-Options "nosniff" always; 5 6# 启用浏览器 XSS 过滤器(兼容旧版浏览器) 7add_header X-XSS-Protection "1; mode=block" always; 8 9# 允许同域名 iframe 嵌套,阻止跨域嵌套 10add_header X-Frame-Options "SAMEORIGIN" always; 11 12# 同域名携带完整 Referrer,跨域仅传域名 13add_header Referrer-Policy "strict-origin-when-cross-origin" always; 14 15# 禁止 Flash/PDF 跨域策略文件加载 16add_header X-Permitted-Cross-Domain-Policies "none" always; 17 18# 禁止 IE 直接打开下载文件 19add_header X-Download-Options "noopen" always; 20 21# 仅允许同站资源加载(防止 Spectre 等旁信道攻击) 22add_header Cross-Origin-Resource-Policy "same-site" always; 23 24# 禁用不必要的浏览器硬件/API 权限 25add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), fullscreen=(self)" always; 26 27# 内容安全策略:仅允许同域名资源 28add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-src 'self'; frame-ancestors 'self'; form-action 'self';" always;

退出登录接口单独配置 Clear-Site-Data

Plain
1# 仅在退出登录接口响应时清除客户端数据 2location = /api/logout { 3 proxy_pass http://your_backend; 4 add_header Clear-Site-Data '"cache", "cookies", "storage"' always; 5}

⚠️ Nginx add_header 继承陷阱

Nginx 中,子级 location 块一旦使用了 add_header,父级 server 块的所有 add_header 配置将全部失效

解决方案:将所有安全头提取到独立文件,在每个有 add_headerlocation 块中 include 进来:

Yaml
1location /some-path { 2 include conf.d/security-headers.conf; 3 add_header Cache-Control "no-store"; 4 # ... 5}

四、Next.js 15 配置

Next.js 支持通过 next.config.mjsheaders() 方法配置响应头,无需依赖 Nginx 即可覆盖大部分场景:

JavaScript
1// next.config.mjs 2const securityHeaders = [ 3 { key: 'X-Content-Type-Options', value: 'nosniff' }, 4 { key: 'X-XSS-Protection', value: '1; mode=block' }, 5 { key: 'X-Frame-Options', value: 'SAMEORIGIN' }, 6 { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, 7 { key: 'X-Permitted-Cross-Domain-Policies', value: 'none' }, 8 { key: 'X-Download-Options', value: 'noopen' }, 9 { key: 'Cross-Origin-Resource-Policy', value: 'same-site' }, 10 { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=(), payment=(), usb=(), fullscreen=(self)' }, 11 { 12 key: 'Content-Security-Policy', 13 value: [ 14 "default-src 'self'", 15 "script-src 'self'", 16 "style-src 'self' 'unsafe-inline'", 17 "img-src 'self' data:", 18 "font-src 'self'", 19 "frame-src 'self'", 20 "frame-ancestors 'self'", 21 "form-action 'self'", 22 ].join('; '), 23 }, 24] 25 26const nextConfig = { 27 async headers() { 28 return [ 29 { 30 source: '/(.*)', // 匹配所有路由 31 headers: securityHeaders, 32 }, 33 ] 34 }, 35} 36 37export default nextConfig

Next.js 配置的覆盖范围限制

Next.js 的 headers() 只作用于 Next.js 处理的路由响应,以下情况不会附加安全头:

  • public/ 目录下的静态文件(由 Nginx/CDN 直接托管时)
  • Next.js 进程之外的 Nginx 层响应(如 Nginx 自身返回的 404)

推荐做法:Next.js config 负责应用层路由,Nginx 负责兜底静态资源和错误页,两端同时配置。


五、CSP 按需调整

默认的 CSP 策略较为严格,实际项目中常见的调整场景:

Yaml
1# 引入了 CDN 上的 JS 库 2script-src 'self' https://cdnjs.cloudflare.com; 3 4# 使用了 Google Fonts 5font-src 'self' https://fonts.gstatic.com; 6style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; 7 8# 需要加载第三方图片 9img-src 'self' data: https://your-cdn.com;

CSP 调整前建议先用 Content-Security-Policy-Report-Only 模式观察拦截情况,再切换为强制模式,避免直接阻断线上业务。