クロスサイトリクエストフォージェリ(CSRF)

ブラウザーが自動送信する認証情報を悪用した意図しないリクエストを防いでください。

説明

CSRFは、ブラウザーがCookieなどの認証情報を自動送信する状況で、被害者が意図しないリクエストを送らせる攻撃です。サーバーがリクエストの正当性を確認しなければ、被害者の権限で操作が実行される可能性があります。

想定される影響

  • 被害者の権限でアカウント設定やデータが変更される可能性があります。
  • 重要な機能が公開されていれば、サービスの中断や権限の悪用につながるおそれがあります。
  • 情報の公開・転送設定を変えられると、データが漏えいする可能性があります。CSRF自体が攻撃者に応答本文を読ませるわけではありません。

対処方法

  • フレームワークのCSRF対策を使うか、セッションに結び付けた予測不能なトークンを発行し、状態変更前に検証してください。
  • SameSite Cookie属性は追加の防御として使い、トークン検証の代わりになるとは考えないでください。
  • CORSとリクエスト送信元の検証を確認し、重要な操作には再認証などを追加してください。

例

コントローラーメソッドの抜粋です。別のフィルターがCSRFを検証しているか確認してください。変更後の例は、サーバーが予測不能なcsrf_tokenを発行し、セッションとフォームへ安全に渡している前提です。

変更前

java
@PostMapping("/update")
public String updateData(HttpServletRequest request) {
    String data = request.getParameter("data");
    // データを更新する処理

    return "updateSuccess";
}

変更後

java
@PostMapping("/update")
public String updateData(@RequestParam("csrf_token") String csrfToken, HttpServletRequest request) {
    String sessionCsrfToken = (String) request.getSession().getAttribute("csrf_token");
    if (sessionCsrfToken == null || !sessionCsrfToken.equals(csrfToken)) {
        throw new SecurityException("CSRF Token mismatch");
    }

    String data = request.getParameter("data");
    // データを更新する処理

    return "updateSuccess";
}

説明:

  • 変更前: このメソッドにはCSRF検証がありません。他の層にも保護がなければ、Cookie認証のリクエストが悪用されるおそれがあります。
  • 変更後: リクエストのトークンとセッションのトークンが一致することを確認してから操作します。ユーザー認証と操作ごとの権限確認は別途必要です。

関連CVE

参考資料