概要
Cross-Site Request Forgery(CSRF)
攻撃を防ぐために、Next.js
でCSRFトークンを実装する方法を解説します。CSRF攻撃は、悪意のあるウェブサイトがユーザーに気づかれないままリクエストを送信させる攻撃です。これを防ぐために、状態を変更するAPIリクエストにはCSRFトークンを含め、サーバーがその正当性を検証する必要があります。
CSRFトークンの仕組み
CSRFトークンは、サーバー
が知っているシークレットキーを基に生成され、ユーザーのセッションに紐付けられます。トークンは次のような手順で生成・検証されます。
- トークン生成: サーバーはシークレットとソルトを組み合わせ、クライアントに返すトークンを生成します。
- クライアントのトークン送信: クライアントはこのトークンをリクエストのカスタムヘッダーとクッキーに含めて送信します。
- トークンの検証: サーバーは、送信されたトークンが正しいかどうかを検証し、一致すればリクエストを処理します。
実装手順
必要なライブラリのインストール
CSRFトークンをサポートするために、next-csrf
のようなライブラリを使用します。以下はその設定方法の一例です。
npm install next-csrf
CSRFトークンのセットアップ
まず、環境変数にシークレットを設定します。
# .env.local
NEXT_CSRF_SECRET="your_random_secret_key"
次に、CSRFトークンの生成とAPI保護を行うlib/csrf.js
を作成します。
import { nextCsrf } from 'next-csrf';
const { csrf, setup } = nextCsrf({
secret: process.env.NEXT_CSRF_SECRET,
});
export { csrf, setup };
APIルートの保護
APIルートにCSRFトークンを検証するミドルウェアを適用します。これにより、POSTやDELETEリクエストなど、セキュアな操作に対してCSRF保護が有効になります。
import { csrf } from '../../lib/csrf';
const handler = (req, res) => {
return res.status(200).json({ message: "Protected API" });
};
export default csrf(handler);
フロントエンドでのトークン使用
トークンを含めてAPIにリクエストを送信する必要があります。ログインページなどのサーバーサイドレンダリング(SSR
)ページでCSRFトークンを設定し、フォームの送信時にこのトークンを含めます。
import { setup } from '../lib/csrf';
export const getServerSideProps = setup(async ({ req, res }) => {
return { props: {} };
});
このようにして、トークンが適切にクライアントにセットされ、送信されるようになります。
使用例と検証
CSRFトークンの動作を検証するには、クライアントが適切にトークンを送信し、それがサーバーで正しく検証されているかを確認します。curlを使ってテストすることも可能です。
curl -X POST http://localhost:3000/api/protected -H "X-CSRF-Token: your_token" --cookie "XSRF-TOKEN=your_cookie_token"
まとめ
CSRFトークンは、状態を変更するAPIリクエストに対する重要なセキュリティ対策です。Next.js
では、next-csrf
ライブラリを使用して簡単にCSRFトークンを実装できます。APIルートを保護することで、セキュリティを強化し、悪意のあるリクエストからユーザーを守ることができます。