CSRF 與 SameSite
攻擊原理
使用者登入銀行後,不小心點擊了駭客的連結:
<img src="https://bank.com/transfer?to=hacker&amount=10000" />
瀏覽器會自動帶上銀行的 Cookie,如果銀行沒做 CSRF 防護,錢就被轉走了!
Vibe Prompt
「幫我在 Next.js API Route 中實作 CSRF Token 驗證。」
// lib/csrf.js
import { createHash, randomBytes } from 'crypto'
const SECRET = process.env.CSRF_SECRET || randomBytes(32).toString('hex')
export function generateCsrfToken(sessionId) {
const hash = createHash('sha256')
hash.update(`${sessionId}:${SECRET}`)
return hash.digest('hex')
}
export function validateCsrfToken(token, sessionId) {
const expected = generateCsrfToken(sessionId)
return token === expected
}
// app/api/transfer/route.js
import { validateCsrfToken } from '@/lib/csrf'
export async function POST(request) {
const body = await request.json()
const sessionId = request.cookies.get('session_id')?.value
if (!validateCsrfToken(body.csrf_token, sessionId)) {
return Response.json({ error: 'CSRF 驗證失敗' }, { status: 403 })
}
// 處理轉帳...
}
SameSite Cookie 設定
// 設定 Cookie 時加入 SameSite
response.cookies.set('session_id', token, {
httpOnly: true,
secure: true,
sameSite: 'strict', // 最嚴格:完全禁止跨站攜帶
maxAge: 60 * 60 * 24
})