hn-hlw-pc/SECURITY_HEADERS.md
2026-07-27 11:32:24 +08:00

237 lines
6.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 安全响应头配置指南
本文档说明如何在生产环境中配置安全响应头,防止点击劫持等安全攻击。
## 已实施的安全措施
### 1. 开发环境Vite
已在 `vite.config.js` 中配置以下响应头:
- `X-Frame-Options: SAMEORIGIN` - 只允许同源页面嵌入
- `X-Content-Type-Options: nosniff` - 防止 MIME 类型嗅探
- `X-XSS-Protection: 1; mode=block` - 启用 XSS 过滤
- `Content-Security-Policy: frame-ancestors 'self'` - CSP 防止点击劫持
### 2. HTML Meta 标签
`index.html` 中添加了 CSP meta 标签作为备用防护。
## 生产环境配置
### Nginx 配置
在 Nginx 配置文件中添加以下响应头:
```nginx
server {
listen 80;
server_name your-domain.com;
# 安全响应头配置
# 防止点击劫持攻击
add_header X-Frame-Options "SAMEORIGIN" always;
# 如果要完全禁止被嵌入,使用:
# add_header X-Frame-Options "DENY" always;
# 防止 MIME 类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# XSS 保护
add_header X-XSS-Protection "1; mode=block" always;
# 内容安全策略CSP- 现代替代方案
add_header Content-Security-Policy "frame-ancestors 'self'" always;
# 强制 HTTPS可选但推荐
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 引用策略
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location / {
root /path/to/your/dist;
try_files $uri $uri/ /index.html;
}
}
```
### Apache 配置
`.htaccess` 或 Apache 配置文件中添加:
```apache
<IfModule mod_headers.c>
# 防止点击劫持攻击
Header always set X-Frame-Options "SAMEORIGIN"
# 如果要完全禁止被嵌入,使用:
# Header always set X-Frame-Options "DENY"
# 防止 MIME 类型嗅探
Header always set X-Content-Type-Options "nosniff"
# XSS 保护
Header always set X-XSS-Protection "1; mode=block"
# 内容安全策略
Header always set Content-Security-Policy "frame-ancestors 'self'"
# 强制 HTTPS可选但推荐
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# 引用策略
Header always set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
```
### Node.js/Express 配置
如果使用 Express 作为服务器:
```javascript
const express = require('express');
const helmet = require('helmet'); // 推荐使用 helmet 中间件
const app = express();
// 使用 helmet 中间件(推荐)
app.use(helmet({
frameguard: {
action: 'sameorigin' // 或 'deny'
},
contentSecurityPolicy: {
directives: {
frameAncestors: ["'self'"]
}
}
}));
// 或手动设置响应头
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Content-Security-Policy', "frame-ancestors 'self'");
next();
});
app.use(express.static('dist'));
```
### 腾讯云静态网站托管配置
如果使用腾讯云静态网站托管,可以在 `cloudbaserc.json` 中添加:
```json
{
"envId": "your-env-id",
"framework": {
"name": "vue",
"plugins": {
"client": {
"path": "./package/dist",
"headers": [
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
},
{
"key": "Content-Security-Policy",
"value": "frame-ancestors 'self'"
}
]
}
}
}
}
```
## X-Frame-Options 选项说明
### SAMEORIGIN
- **含义**:只允许同源(相同域名)的页面嵌入当前页面
- **使用场景**:当你需要在自己网站的其他页面中嵌入当前页面时
- **安全性**:中等,可防止外部网站的点击劫持攻击
### DENY
- **含义**:完全禁止任何页面嵌入当前页面
- **使用场景**:当你确定页面不需要被任何 iframe 嵌入时
- **安全性**:最高,提供最强的点击劫持防护
### ALLOW-FROM uri已废弃
- **含义**:允许特定 URI 的页面嵌入
- **状态**:已被主流浏览器废弃,不推荐使用
- **替代方案**:使用 CSP 的 `frame-ancestors` 指令
## CSP frame-ancestors 指令
CSP 的 `frame-ancestors``X-Frame-Options` 的现代替代方案,提供更灵活的控制:
```
Content-Security-Policy: frame-ancestors 'none' # 等同于 X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'self' # 等同于 X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self' https://trusted.com # 允许特定域名
```
## 验证配置
### 方法1浏览器开发者工具
1. 打开网站
2. 按 F12 打开开发者工具
3. 切换到 Network网络标签
4. 刷新页面
5. 点击主文档请求
6. 查看 Response Headers响应头
7. 确认 `X-Frame-Options``Content-Security-Policy` 存在
### 方法2命令行测试
```bash
curl -I https://your-domain.com
```
### 方法3在线工具
- [SecurityHeaders.com](https://securityheaders.com/)
- [Mozilla Observatory](https://observatory.mozilla.org/)
## 测试点击劫持防护
创建一个测试 HTML 文件:
```html
<!DOCTYPE html>
<html>
<head>
<title>点击劫持测试</title>
</head>
<body>
<h1>尝试嵌入目标网站</h1>
<iframe src="https://your-domain.com" width="800" height="600"></iframe>
</body>
</html>
```
如果配置正确iframe 将无法加载目标页面,浏览器控制台会显示类似错误:
```
Refused to display 'https://your-domain.com' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
```
## 注意事项
1. **选择合适的策略**:根据业务需求选择 `SAMEORIGIN``DENY`
2. **同时使用多层防护**:建议同时配置 `X-Frame-Options` 和 CSP `frame-ancestors`
3. **HTTPS**:始终使用 HTTPS 以确保安全头不会被中间人攻击篡改
4. **测试兼容性**:部署后测试所有功能是否正常工作
5. **定期审计**:定期检查安全配置是否有效
## 相关资源
- [OWASP Clickjacking Defense Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html)
- [MDN: X-Frame-Options](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/X-Frame-Options)
- [MDN: CSP frame-ancestors](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)