Web应用暴露在公网时,仅靠后端逻辑难以防住所有客户端侧的攻击。Nginx作为流量入口,可在响应阶段统一注入安全头部,用浏览器自身的安全机制约束页面行为。这种做法对业务代码零侵入,却能有效缓解点击劫持、跨站脚本传播、敏感信息泄露等问题。理解每个头部的语义和配置边界,是运维和开发都该具备的基础能力。

核心安全头部的作用与Nginx配置写法
X-Frame-Options 是最早被用于防点击劫持的响应头,它告诉浏览器是否允许当前页面在 <frame>、<iframe> 或 <object> 中展现。可选值有 DENY 和 SAMEORIGIN,前者彻底禁止嵌入,后者仅允许同源域名嵌入。在Nginx里通过 add_header 指令即可下发,需要注意该指令默认不会继承到错误响应,若想全覆盖应加上 always 参数。
X-Content-Type-Options 的取值固定为 nosniff,作用是禁止浏览器对响应内容做MIME嗅探。例如后端错误地把脚本文件标成 text/plain,浏览器本可能仍按脚本执行,有了这个头就能强制按声明类型处理。配置时同样使用 add_header X-Content-Type-Options nosniff always;。它与前一个头部互不冲突,应同时开启。
另一个关键头部是 Referrer-Policy,它控制浏览器在跳转时携带多少来源信息。设为 no-referrer 可避免把内部URL泄露给第三方,但也可能影响一些依赖来源的统计。更温和的写法是 strict-origin-when-cross-origin,在同源时带完整路径,跨域时只带域名。下面给出一段基础配置示例:
server {
listen 80;
server_name example.ipipp.com;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
内容安全策略CSP的部署与误配排查
Content-Security-Policy(简称CSP)是现代浏览器最核心的防护头部,它通过白名单机制限定脚本、样式、图片、连接等资源的加载源。一个严格策略如 default-src 'self'; script-src 'self' 表示默认只允许同源资源,脚本也仅限同源。这能大幅压缩XSS攻击面,因为外域恶意脚本无法执行。在Nginx中配置时,整条策略作为头部值直接写出,注意引号要用单引号且不能遗漏。
实际落地常遇到误配导致页面白屏。比如用了 script-src 'self' 却通过CDN引入前端框架,浏览器会拦截并报错。此时需把CDN域名加入白名单:script-src 'self' https://cdn.ipipp.com。若页面内联了脚本,还需评估是否使用 'unsafe-inline',但这会削弱防护,更推荐用随机数 nonce 方式。下面示例展示带nonce的Nginx与后端协作思路:
server {
listen 443 ssl;
server_name app.ipipp.com;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-abc123'" always;
location / {
proxy_pass http://192.168.0.1:3000;
}
}
CSP还支持上报模式 Content-Security-Policy-Report-Only,它不阻塞资源只收集违规日志,适合迁移期使用。很多团队直接全量开启严格策略造成故障,正确做法是先Report-Only观察一周,再用Nginx变量动态注入nonce,最后切到强制模式。这种渐进式部署能平衡安全与稳定。
HTTPS增强头部与全局配置最佳实践
启用了TLS后,还应配置 Strict-Transport-Security(HSTS)强制客户端走HTTPS。写法如 max-age=31536000; includeSubDomains 表示一年内浏览器自动把域名及子域转HTTPS。但要注意一旦下发,撤回极难,测试环境勿轻易开启 includeSubDomains。Nginx里同样用 add_header 下发,且必须仅在HTTPS的server块中设置。
为了统一管理,可将安全头部抽成单独文件 security_headers.conf,再在多个server中用 include 引入,避免重复书写。但要注意 add_header 有作用域覆盖特性:如果某location块自己写了 add_header,外层server的头部不会自动合并,必须在该块重新声明或改用 more_set_headers(需安装Headers More模块)。这种细节常导致安全头部在API路径上丢失。
最后建议配合自动化检测。部署后用 curl -I https://app.ipipp.com 查看响应头是否齐全,或借助在线扫描服务。下表列出推荐最小值:
| 头部名称 | 推荐值 | 防护目标 |
|---|---|---|
| X-Frame-Options | SAMEORIGIN | 点击劫持 |
| X-Content-Type-Options | nosniff | MIME嗅探 |
| Content-Security-Policy | default-src 'self' | XSS与注入 |
| Strict-Transport-Security | max-age=31536000 | 中间人降级 |
把上述头部固化进Nginx模板,新站点上线即自带基线防护,既降低运维负担,也减少人为遗漏带来的暴露面。
Nginxsecurity_headersHTTP_response修改时间:2026-08-18 08:18:17