csrf-protection について
csrf-protection は、Web アプリケーションを CSRF から守る開発者向けのセキュリティスキルです。同期トークン、二重送信 Cookie、SameSite 設定などの対策と実装上の指針を扱います。
主な機能
- 01同期トークン検証
- 02二重送信 Cookie
- 03SameSite Cookie による保護
- 04Origin/Referer 検証の指針
- 05Express と Flask-WTF の例
活用シーン
- 01状態変更リクエストの CSRF 対策
- 02フォームへのトークン検証追加
- 03Cookie とリクエスト元設定の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill csrf-protectionインストール後、Claude Code で/csrf-protectionを入力して読み込まれたか確認します。
同梱ファイルreferences/python-react.md
詳細
CSRF 保護
複数の保護層を使用して、クロスサイトリクエストフォージェリ攻撃を防ぎます。
保護方法
| 方法 | 仕組み | ブラウザーのサポート |
|---|---|---|
| 同期トークン | 非表示のフォームフィールドをサーバー側で検証 | すべて |
| ダブルサブミット | Cookie とヘッダーが一致する必要があります | すべて |
| SameSite Cookie | ブラウザーがクロスオリジンリクエストをブロック | モダンブラウザー |
トークンベースの保護(Express)
const crypto = require('crypto');
function generateToken() {
return crypto.randomBytes(32).toString('hex');
}
// Middleware
app.use((req, res, next) => {
if (!req.session.csrfToken) {
req.session.csrfToken = generateToken();
}
res.locals.csrfToken = req.session.csrfToken;
next();
});
// Validation
app.post('*', (req, res, next) => {
const token = req.body._csrf || req.headers['x-csrf-token'];
// crypto.timingSafeEqual throws RangeError when buffers differ in length,
// so check length explicitly first (still constant-time on the equal-length path).
const csrf = req.session.csrfToken || '';
if (!token || token.length !== csrf.length) {
return res.status(403).json({ error: 'Invalid CSRF token' });
}
if (!crypto.timingSafeEqual(Buffer.from(token), Buffer.from(csrf))) {
return res.status(403).json({ error: 'Invalid CSRF token' });
}
next();
});
SameSite Cookie
app.use(session({
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict', // or 'lax'
maxAge: 3600000
}
}));
HTML フォームとの統合
<form method="POST" action="/transfer">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit">Submit</button>
</form>
ベストプラクティス
- 状態を変更するすべてのリクエスト(POST、PUT、DELETE)に適用します
- 機密性の高い Cookie には SameSite=Strict を使用します
- Origin/Referer ヘッダーを検証します
- 変更処理に GET を使用しないでください
- トークンの有効期限を設定します(一般的には1時間)
- 複数の防御層を組み合わせます
その他の実装
以下を参照してください:references/python-react.md:
- Flask-WTF による完全な CSRF セットアップ
- CSRF トークン管理用の React フック
- ダブルサブミット Cookie パターン
よくある間違い
- 認証によって CSRF が防止されると思い込む
- セッション間でトークンを再利用する
- localStorage にトークンを保存する
- トークンの有効期限を設定しない
コメント
Markdown 対応