网站安全头部配置指南:CSP / HSTS / X-Frame-Options 详解
HTTP 安全头部是浏览器端安全的第一道防线。通过配置正确的安全头部,可以有效防御 XSS、点击劫持、MIME 嗅探等攻击。安全头部配置简单、成本极低,但防御效果显著。
一、核心安全头部
1.1 Content-Security-Policy (CSP)
CSP 是防御 XSS 和注入攻击的最强武器。它告诉浏览器哪些来源的资源是可信的。
# Nginx 配置
add_header Content-Security-Policy "
default-src 'self';
script-src 'self' 'unsafe-inline' https://trusted-cdn.com;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' data: https:;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://api.example.com;
frame-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
" always;
CSP 指令详解:
| 指令 | 控制内容 | 建议值 |
|---|---|---|
default-src |
所有资源的默认来源 | 'self' |
script-src |
JavaScript 来源 | 'self' 或特定 CDN |
style-src |
CSS 来源 | 'self' 或特定 CDN |
img-src |
图片来源 | 'self' data: https: |
connect-src |
API/XHR/Fetch 来源 | 'self' 或 API 域名 |
font-src |
字体来源 | 'self' 或字体 CDN |
frame-src |
iframe 来源 | 'self' |
object-src |
Flash/Java 来源 | 'none' |
base-uri |
<base> 标签 |
'self' |
form-action |
表单提交目标 | 'self' |
CSP 部署策略:
阶段 1:仅报告模式(观察是否有违规)
Content-Security-Policy-Report-Only: ...; report-uri /csp-report
阶段 2:宽松策略(逐步收紧)
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https:;
阶段 3:严格策略(去掉 unsafe-inline)
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;
1.2 Strict-Transport-Security (HSTS)
HSTS 告诉浏览器始终使用 HTTPS 连接你的网站,即使用户输入 HTTP 地址。
# 初始配置(短时间,观察是否有问题)
add_header Strict-Transport-Security "max-age=3600; includeSubDomains" always;
# 生产配置(1 年)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
HSTS preload:
将网站提交到 https://hstspreload.org 后,你的域名会被硬编码到浏览器中,即使用户从未访问过你的网站,浏览器也会使用 HTTPS。
要求:
- HSTS 头部必须设置
max-age至少 31536000(1 年) - 必须设置
includeSubDomains - 网站必须完全通过 HTTPS 访问(无 HTTP 内容)
1.3 X-Frame-Options
防止点击劫持攻击,控制页面能否被嵌入 iframe。
# 拒绝被任何页面嵌入(推荐)
add_header X-Frame-Options "DENY" always;
# 仅允许同源页面嵌入
add_header X-Frame-Options "SAMEORIGIN" always;
注意:
X-Frame-Options的优先级高于 CSP 的frame-ancestors。如果两者都设置,X-Frame-Options规则优先。
1.4 X-Content-Type-Options
防止浏览器 MIME 类型嗅探攻击:
add_header X-Content-Type-Options "nosniff" always;
当设置为 nosniff 时,浏览器会严格遵循服务器返回的 Content-Type 头,不会自行猜测文件类型。这可以防止攻击者上传伪装成图片的 HTML 文件。
1.5 Referrer-Policy
控制 HTTP 请求中 Referer 头携带的信息量:
# 推荐:同源请求发送完整 Referer,跨域请求仅发送来源
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
可选值:
| 值 | 行为 |
|---|---|
no-referrer |
不发送 Referer |
same-origin |
仅同源请求发送 |
strict-origin |
仅发送来源域名(HTTPS→HTTPS) |
strict-origin-when-cross-origin |
推荐:同源完整,跨域仅域名 |
unsafe-url |
始终发送完整 URL(不推荐) |
1.6 Permissions-Policy
控制浏览器 API 权限:
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()" always;
二、完整安全头部配置
Nginx 推荐配置
# /etc/nginx/conf.d/security-headers.conf
# 安全头部配置
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()" always;
# CSP - 根据您的网站实际情况调整
add_header Content-Security-Policy "
default-src 'self';
script-src 'self' 'unsafe-inline' https:;
style-src 'self' 'unsafe-inline' https:;
img-src 'self' data: https:;
font-src 'self' https:;
connect-src 'self' https:;
frame-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
" always;
Apache 推荐配置
# .htaccess 或 httpd.conf
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self' https:; frame-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'"
三、验证安全头部
在线工具
- Security Headers (https://securityheaders.com) - 评分制检测
- Mozilla Observatory (https://observatory.mozilla.org) - 全面安全评估
- CSP Evaluator (https://csp-evaluator.withgoogle.com) - CSP 规则评估
命令行检查
# 使用 curl 检查安全头部
curl -sI https://example.com | grep -i "security\|csp\|hsts\|frame"
# 示例输出
strict-transport-security: max-age=31536000; includeSubDomains
x-frame-options: DENY
x-content-type-options: nosniff
content-security-policy: default-src 'self'; script-src 'self'
四、常见问题
CSP 导致功能异常
CSP 过于严格可能导致某些功能失效:
问题:第三方脚本(如 Google Analytics)被阻止
解决:在 CSP 中添加第三方域名
script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com;
HSTS 导致 HTTP 网站无法访问
如果在开发阶段错误启用了 HSTS,可能导致本地开发环境无法访问:
# Chrome 清除 HSTS
chrome://net-internals/#hsts
# 在 Domain 中输入域名,点击 Delete
五、总结
HTTP 安全头部是性价比最高的安全措施之一。只需在 Web 服务器配置中添加几行代码,就能防御多种常见攻击。建议逐步部署:首先添加 X-Frame-Options、X-Content-Type-Options 和 Referrer-Policy(这些基本不会影响现有功能),然后逐步部署 CSP 和 HSTS。使用 SecurityHeaders.com 检测评分,目标是达到 A 级或 A+ 级。