.. _SpringSecurityCsrf:
CSRF対策
================================================================================
.. only:: html
.. contents:: 目次
:local:
Overview
--------------------------------------------------------------------------------
本節では、Spring Securityが提供しているCross site request forgeries(以下、CSRFと略す)対策の機能について説明する。
CSRFとは、Webサイトにスクリプトや自動転送(HTTPリダイレクト)を実装することにより、ログイン済みの別のWebサイト上で、ユーザーが意図しない何らかの操作を行わせる攻撃手法のことである。
サーバ側でCSRFを防ぐには、以下の方法が知られている。
* 秘密情報(トークン)の埋め込み
* パスワードの再入力
* Refererのチェック
| CSRF対策機能は、攻撃者が用意したWebページから送られてくる偽造リクエストを不正なリクエストとして扱うための機能である。
| CSRF対策が行われていないWebアプリケーションを利用すると、以下のような方法で攻撃を受ける可能性がある。
* 利用者は、CSRF対策が行われていないWebアプリケーションにログインする。
* 利用者は、攻撃者からの巧みな誘導によって、攻撃者が用意したWebページを開いてしまう。
* 攻撃者が用意したWebページは、フォームの自動送信などのテクニックを使用して、偽造したリクエストをCSRF対策が行われていないWebアプリケーションに対して送信する。
* CSRF対策が行われていないWebアプリケーションは、攻撃者が偽造したリクエストを正規のリクエストとして処理してしまう。
.. tip::
\ `OWASP `_\ \ [#fSpringSecurityCSRF1]_\では、\ `トークンパターンを使用する方法が推奨されている。 `_\
.. [#fSpringSecurityCSRF1] Open Web Application Security Projectの略称であり、信頼できるアプリケーションや、セキュリティに関する 効果的なアプローチなどを検証、提唱する、国際的な非営利団体である。
.. note:: \ **ログイン時におけるCSRF対策**\
CSRF対策はログイン中のリクエストだけではなく、ログイン処理でも行う必要がある。
ログイン処理に対してCSRF対策を怠った場合、攻撃者が用意したアカウントを使って知らぬ間にログインさせられ、ログイン中に行った操作履歴などを盗まれる可能性がある。
.. warning:: \ **マルチパートリクエスト(ファイルアップロード)時におけるCSRF対策**\
ファイルアップロード時のCSRF対策については、\ :ref:`ファイルアップロード Servlet Filterの設定 `\ を留意されたい。
|
Spring SecurityのCSRF対策
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Spring Securityは、セッション単位にランダムに生成される固定トークン値(CSRFトークン)を払い出し、払い出されたCSRFトークンをリクエストパラメータ(HTMLフォームのhidden項目)として送信する。
| これにより正規のWebページからのリクエストなのか、攻撃者が用意したWebページからのリクエストなのかを判断する仕組みを採用している。
.. figure:: ./images_CSRF/Csrf.png
:width: 100%
\ **Spring SecurityのCSRF対策の仕組み**\
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- | クライアントは、HTTPのGETメソッドを使用してアプリケーションサーバにアクセスする。
* - | (2)
- | Spring Securityは、CSRFトークンを生成しHTTPセッションに格納する。
| 生成したCSRFトークンは、HTMLフォームのhiddenタグを使ってクライアントと連携する。
* - | (3)
- | クライアントは、HTMLフォーム内のボタンを押下してアプリケーションサーバーにリクエストを送信する。
| HTMLフォーム内のhidden項目にCSRFトークンが埋め込まれているため、CSRFトークン値はリクエストパラメータとして送信される。
* - | (4)
- | Spring Securityは、HTTPのPOSTメソッドを使ってアクセスされた際は、リクエストパラメータに指定されたCSRFトークン値とHTTPセッション内に保持しているCSRFトークン値が同じ値であることをチェックする。
| トークン値が一致しない場合は、不正なリクエスト(攻撃者からのリクエスト)としてエラーを発生させる。
* - | (5)
- | クライアントは、HTTPのGETメソッドを使用してアプリケーションサーバにアクセスする。
* - | (6)
- | Spring Securityは、GETメソッドを使ってアクセスされた際は、CSRFトークン値のチェックは行わない。
.. note:: \ **Ajax使用時のCSRFトークン**\
Spring Securityは、リクエストヘッダにCSRFトークン値を設定することができるため、Ajax向けのリクエストなどに対してCSRF対策を行うことが可能である。
|
.. _csrf_ckeck-target:
トークンチェックの対象リクエスト
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Spring Securityのデフォルト実装では、以下のHTTPメソッドを使用したリクエストに対して、CSRFトークンチェックを行う。
* POST
* PUT
* DELETE
* PATCH
.. note:: \ **CSRFトークンチェックを行わない理由**\
GET, HEAD, OPTIONS, TRACE メソッドがチェック対象外となっている理由は、これらのメソッドがアプリケーションの状態を変更するようなリクエストを実行するためのメソッドではないためである。
|
.. _csrf_spring-security-setting:
How to use
--------------------------------------------------------------------------------
CSRF対策機能の適用
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CSRFトークン用の\ ``RequestDataValueProcessor``\ 実装クラスを利用し、Springのタグライブラリの\ ````\ タグを使うことで、自動的にCSRFトークンを、hidden項目に埋め込むことができる。
* spring-mvc.xmlの設定例
.. code-block:: xml
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- | \ 共通ライブラリから提供されている、\ ``org.springframework.web.servlet.support.RequestDataValueProcessor``\ を複数定義可能な
| \ ``org.terasoluna.gfw.web.mvc.support.CompositeRequestDataValueProcessor``\ をbean定義する。
* - | (2)
- | コンストラクタの第1引数に、\ ``org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor``\ のbean定義を設定する。
上記設定により、デフォルトでCSRF対策機能が有効となる。このため、CSRF対策機能を適用したくない場合は、明示的に無効化する必要がある。
CSRF対策機能を使用しない場合は、以下のようなbean定義を行う。
* spring-security.xmlの定義例
.. code-block:: xml
|
CSRFトークン値の連携
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Spring Securityは、CSRFトークン値をクライアントとサーバー間で連携する方法として、以下の2種類の方法を提供している。
* HTMLフォームのhidden項目としてCSRFトークン値を出力し、リクエストパラメータとして連携する
* HTMLのmetaタグとしてCSRFトークンの情報を出力し、Ajax通信時にリクエストヘッダにトークン値を設定して連携する
|
.. _csrf_formtag-use:
Spring MVCを使用した連携
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| Spring Securityは、Spring MVCと連携するためのコンポーネントをいくつか提供している。
| ここでは、CSRF対策機能と連携するためのコンポーネントの使い方を説明する。
|
hidden項目の自動出力
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
HTMLフォームを作成する際は、以下のようなJSPの実装を行う。
* JSPの実装例
.. code-block:: jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- | HTMLフォームを作成する際は、Spring MVCから提供されている\ ````\ 要素を使用する。
Spring MVCから提供されている\ ````\ 要素を使うと、以下のようなHTMLフォームが作成される。
* HTMLの出力例
.. code-block:: html
.. tip:: \ **出力されるCSRFトークンチェック値**\
\ ``CsrfRequestDataValueProcessor``\ を使用すると、\ ````\ タグの\ ``method``\ 属性に指定した値がCSRFトークンチェック対象のHTTPメソッド(Spring Securityのデフォルト実装ではGET,HEAD,TRACE,OPTIONS以外のHTTPメソッド)と一致する場合に限り、CSRFトークンが埋め込まれた\ ````\ タグが出力される。
例えば、以下の例のように \ ``method``\ 属性にGETメソッドを指定した場合は、CSRFトークンが埋め込まれた\ ````\ タグは出力されない。
.. code-block:: jsp
<%-- ... --%>
これは、\ `Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet `_\ で説明されている内容に対応している事を意味しており、セキュアなWebアプリケーション構築の手助けとなる。
|
.. _csrf_htmlformtag-use:
HTMLフォーム使用時の連携
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
| \ :ref:`Spring MVCと連携`\ せずに、HTMLフォームを使用してCSRFトークン値を連携することも可能である。
| HTMLフォームを使ってリクエストを送信する場合は、HTMLフォームのhidden項目としてCSRFトークン値を出力し、リクエストパラメータとして連携する。
* JSPの実装例
.. code-block:: text
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
" method="post">
.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
:header-rows: 1
:widths: 10 90
* - 項番
- 説明
* - | (1)
- | HTMLの\ ``