在Web服务安全防护体系中,HTTP安全头是第一道防线。作为高性能的Web服务器,Nginx通过简单的配置就能实现强大的安全防护能力。安全头(Security Headers)是服务器在HTTP响应中返回的特殊字段,它们像交通信号灯一样指导浏览器如何安全地处理网页内容。
我管理过多个高流量电商站点的Nginx配置,深刻体会到合理配置安全头可以阻止80%的常见Web攻击。不同于防火墙等被动防御措施,安全头是主动防御机制,能在攻击发生前就切断攻击路径。比如XSS攻击、点击劫持、MIME类型混淆等威胁,都可以通过安全头有效缓解。
这个头用于控制浏览器的XSS过滤机制。虽然现代浏览器逐渐废弃了这个功能,但在兼容旧系统时仍有价值。推荐配置:
nginx复制add_header X-XSS-Protection "1; mode=block";
这个配置会:
注意:在Chrome 78+和Edge 79+中这个头已失效,应该优先使用Content-Security-Policy来防护XSS
CSP是现代Web安全的基石,我花了三个月时间才为电商站点设计出既安全又不影响业务的CSP策略。基础配置示例:
nginx复制add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' cdn.example.com; img-src * data:; style-src 'self' 'unsafe-inline'";
这个策略包含以下关键点:
部署CSP时最常见的坑是:
建议先用Content-Security-Policy-Report-Only模式观察一段时间。
点击劫持(Clickjacking)通过iframe嵌套你的页面进行恶意操作。防护配置:
nginx复制add_header X-Frame-Options "SAMEORIGIN";
这个头有三个可选值:
实际案例:某金融站点因为漏配这个头,导致攻击者可以将交易页面嵌入钓鱼网站
强制浏览器遵守声明的Content-Type:
nginx复制add_header X-Content-Type-Options "nosniff";
这个头主要解决两类问题:
HSTS告诉浏览器强制使用HTTPS连接:
nginx复制add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
参数说明:
部署HSTS前必须确保:
控制Referer头包含的信息量:
nginx复制add_header Referrer-Policy "strict-origin-when-cross-origin";
这个策略表示:
安全头应该被缓存吗?我的经验是:
nginx复制location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
add_header Cache-Control "public, max-age=31536000";
add_header X-XSS-Protection "1; mode=block";
# 其他安全头...
}
静态资源可以长期缓存,但安全头必须每次返回。注意某些CDN会默认移除安全头,需要特别配置。
根据请求特征动态调整安全头:
nginx复制map $uri $csp_policy {
default "default-src 'self'";
"~*^/admin/" "default-src 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self'";
}
server {
add_header Content-Security-Policy $csp_policy;
}
这个配置对/admin/路径使用更严格策略。
这是我为生产环境优化的完整配置:
nginx复制http {
# 基础安全头
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
# CSP根据不同路径变化
map $request_uri $csp_header {
default "default-src 'self'; script-src 'self' 'unsafe-inline' static.example.com; img-src * data:; style-src 'self' 'unsafe-inline'; font-src 'self' data:;";
"~^/api/" "default-src 'none'; frame-ancestors 'none';";
}
server {
listen 443 ssl;
location / {
add_header Content-Security-Policy $csp_header;
# 其他配置...
}
location /report-csp {
# CSP违规报告收集端点
proxy_pass http://csp-report-collector;
}
}
}
多个安全头可能产生冲突,例如:
X-Frame-Options和Content-Security-Policy的frame-ancestors时,浏览器会采用更严格的策略Content-Security-Policy会覆盖X-XSS-Protection的功能安全头会增加HTTP头部大小,我的实测数据:
调试安全头问题时:
report-uri收集报告我常用的验证工具链:
必须测试的边界情况:
在生产环境监控:
虽然本文介绍的经典安全头仍然有效,但Web安全领域正在发展:
strict-dynamic等指令Permissions-Policy(原Feature-Policy)控制浏览器功能Cross-Origin-Opener-Policy和Cross-Origin-Embedder-Policy应对Spectre攻击保持安全配置更新的建议: