关于 cors-security-headers
cors-security-headers 是面向 Web 应用开发者的安全配置参考技能,展示 Express 和 Spring Boot 中 CORS、安全响应头、CSRF 防护及安全 Cookie 的配置方式。
主要功能
- 01Express CORS 配置
- 02Helmet.js 安全响应头
- 03CSRF 防护模式
- 04安全会话 Cookie 设置
- 05Spring Boot 响应头配置
适用场景
- 01将跨源请求限制为受信任来源
- 02设置内容安全和传输安全响应头
- 03为基于会话的表单防护 CSRF
- 04配置 Web 会话的安全 Cookie
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill cors-security-headers安装后在 Claude Code 中输入/cors-security-headers确认已加载。
详细介绍
CORS 与安全标头
CORS(Express)
import cors from 'cors';
// Restrictive (recommended)
app.use(cors({
origin: ['https://myapp.com', 'https://admin.myapp.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400, // Preflight cache: 24h
}));
// Dynamic origin
app.use(cors({
origin: (origin, callback) => {
const allowed = ALLOWED_ORIGINS.includes(origin!) || !origin; // !origin = same-origin
callback(null, allowed ? origin : false);
},
credentials: true,
}));
安全标头(Helmet.js)
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", 'https://cdn.example.com'],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'", 'https://api.example.com'],
frameSrc: ["'none'"],
objectSrc: ["'none'"],
},
},
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
}));
CSRF 防护
import csrf from 'csurf';
// For server-rendered forms (session-based apps)
app.use(csrf({ cookie: true }));
app.get('/form', (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
// For SPAs: use SameSite cookies + custom header
// No csrf library needed — rely on:
// 1. SameSite=Strict/Lax cookies
// 2. Check Origin/Referer header matches
// 3. Custom header requirement (X-Requested-With)
安全 Cookie
app.use(session({
cookie: {
httpOnly: true, // No JS access
secure: true, // HTTPS only
sameSite: 'lax', // CSRF protection
maxAge: 24 * 60 * 60 * 1000,
domain: '.myapp.com', // Shared across subdomains
},
}));
Spring Boot 安全标头
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.cors(cors -> cors.configurationSource(corsConfig()))
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'"))
.referrerPolicy(ref -> ref.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN))
.frameOptions(frame -> frame.deny())
)
.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
.build();
}
@Bean
CorsConfigurationSource corsConfig() {
var config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://myapp.com"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
config.setAllowCredentials(true);
var source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
关键标头参考
| 标头 | 用途 | 建议值 |
|---|---|---|
Strict-Transport-Security | 强制使用 HTTPS | max-age=31536000; includeSubDomains |
Content-Security-Policy | 限制资源加载 | default-src 'self' + 具体配置 |
X-Content-Type-Options | 防止 MIME 嗅探 | nosniff |
X-Frame-Options | 防止点击劫持 | DENY |
Referrer-Policy | 控制来源信息 | strict-origin-when-cross-origin |
Permissions-Policy | 限制浏览器功能 | camera=(), microphone=() |
反模式
| 反模式 | 修复方案 |
|---|---|
携带凭据时使用 Access-Control-Allow-Origin: * | 指定确切的来源 |
| 未设置 CSP 标头 | 添加 Content-Security-Policy |
| 将 CSRF 令牌放在 URL 查询参数中 | 使用标头或隐藏表单字段 |
使用 SameSite=None 但未设置 Secure | 始终将 SameSite=None 与 Secure 配合使用 |
| 缺少 HSTS | 启用 HSTS,并设置较长的 max-age 和 preload |
生产环境检查清单
- CORS:指定具体来源,携带凭据时不使用通配符
- 为所有安全标头配置 Helmet.js(或同等方案)
- 配置并测试 CSP
- 启用带 preload 的 HSTS
- Cookie 设置 Secure、HttpOnly 和 SameSite
- 为会改变状态的请求启用 CSRF 防护
评论
支持 Markdown