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から保護
- 04Webセッション用の安全な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 を追加する |
| URL クエリパラメーターに CSRF トークンを含める | ヘッダーまたは非表示のフォームフィールドを使う |
Secure なしで SameSite=None を設定する | 常に SameSite=None と Secure を組み合わせる |
| HSTS がない | 長い max-age と preload を設定して有効にする |
本番環境のチェックリスト
- CORS:オリジンを明示的に指定し、認証情報を含む場合にワイルドカードを使わない
- すべてのセキュリティヘッダーに Helmet.js(または同等のもの)を使用する
- CSP を設定してテストする
- preload を設定した HSTS
- Secure、HttpOnly、SameSite を設定した Cookie
- 状態を変更するリクエストに CSRF 保護を適用する
コメント
Markdown 対応