スクリプト開発でのCSRF対策(formタグ編)

Cross Site Request Forgery(CSRF)とは、閲覧者に不正にHTTPリクエストを送信させ、攻撃者の意図した処理を実行させる攻撃手法です。
このCookBookでは、スクリプト開発でformタグを利用する場合のCSRF対策について紹介します。
CSRF対策用のセキュア・トークンを出力するIMARTタグであるimSecureTokenを用いて実装を行います。

セキュア・トークンの詳細な説明は以下のドキュメントを参照してください。
スクリプト開発向けタグライブラリ / imSecureToken

完成イメージ

  1. with_imSecureToken フォームのSubmitボタンをクリックしてください。
  2. セキュア・トークンがリクエストに含まれているため、正常に遷移が行われ、画面にSuccess!と表示されます。
  3. ツールバーの矢印ボタンをクリックしてください。
  4. without_imSecureToken フォームのSubmitボタンをクリックしてください。
  5. セキュア・トークンがリクエストに含まれていないため、403エラー画面が表示されます。

 

[iframe width="100%" height="400" src="https://dev-portal.intra-mart.jp/imart/im_cookbook/113159/CSRF?imui-theme-builder-module=headwithcontainer"]

完成サンプル

以下の完成サンプルをダウンロードしてご活用ください。

e builder プロジェクト : im_cookbook_113159_CSRF.zip
imm ファイル : im_cookbook_113159_CSRF-1.0.0.imm

ローカル環境で表示させる場合は、以下のURLにアクセスしてください。
http://localhost:8080/imart/im_cookbook/113159/CSRF
なおベースURLである以下の部分は、環境に合わせて適宜変更してください。
http://localhost:8080/imart

レシピ

  1. フォーム画面を作成してください。
  2. 遷移後の画面を作成してください。
  3. ルーティング設定ファイルを作成してください。
  4. セキュア・トークンフィルタ設定ファイルを作成してください。

1. フォーム画面を作成してください。

e Builder のモジュールプロジェクト内に以下のhtmlファイルを作成してください。
src/main/jssp/src/im_cookbook_113159_CSRF/CSRF.html

<imart type="head">
  <title>CSRF prevention</title>
  <script>
  $(function(){
      $('#with_submit').click(function(){
          $('#form1').submit();
      });
      $('#without_submit').click(function(){
          $('#form2').submit();
      });
  });
  </script>
</imart>

<div class="imui-title">
  <h1>CSRF prevention</h1>
</div>

<div class="imui-form-container">
  <header class="imui-chapter-title">
    <h2>with_imSecureToken</h2>
  </header>
  <form id="form1" name="form1" action="im_cookbook/113159/CSRF2" method="POST">
    <imart type="imSecureToken" />
  </form>
  <div class="imui-operation-parts">
    <imart type="imuiButton"  id="with_submit" class="imui-large-button" value="Submit"/>
  </div>
</div>

<div class="imui-form-container">
  <header class="imui-chapter-title">
    <h2>without_imSecureToken</h2>
  </header>
  <form id="form2" name="form2" action="im_cookbook/113159/CSRF2" method="POST">
  </form>
  <div class="imui-operation-parts">
    <imart type="imuiButton"  id="without_submit" class="imui-large-button" value="Submit"/>
  </div>
</div>

今回は比較を目的に、セキュア・トークンを含めるformとセキュア・トークンを含めないformの2つを作成してください。
どちらのformも遷移先は im_cookbook/113159/CSRF2 としてください。

セキュア・トークンを含めるformタグの中には <imart type="imSecureToken" /> を記述してください。
imSecureTokenはhiddenタグを生成し、セキュア・トークンを発行するタグです。
このタグを利用することで、直接URLを入力してのアクセスといったセキュア・トークンを発行する画面を経由しないアクセスは、不正なアクセスと見なして遮断することができます。
遮断された場合、403のエラー画面が表示されます。

imSecureTokenの詳細は以下のドキュメントを参照してください。
スクリプト開発向けタグライブラリ / imSecureToken

2. 遷移後の画面を作成してください。

(1) e Builder のモジュールプロジェクト内に以下のhtmlファイルを作成してください。
src/main/jssp/src/im_cookbook_113159_CSRF/CSRF2.html

<imart type="head">
  <title>CSRF prevention</title>
</imart>

<div class="imui-title">
  <h1>CSRF prevention</h1>
</div>

<div class="imui-toolbar-wrap">
  <div class="imui-toolbar-inner">
    <ul class="imui-list-toolbar">
      <li>
        <a href="im_cookbook/113159/CSRF" class="imui-toolbar-tab">
          <span class="im-ui-icon-common-16-back"></span>
        </a>
      </li>
    </ul>
  </div>
</div>

<div class="imui-form-container">Success!</div>

この画面は、ページが表示された際に「Succsess!」と表示する画面です。
遷移前のフォーム画面に戻るボタンをツールバーに配置しています。

3. ルーティング設定ファイルを作成してください。

e Builder のモジュールプロジェクト内に以下のxmlファイルを作成してください。
src/main/conf/rooting-jssp-config/im_cookbook_113159_CSRF.xml

<?xml version="1.0" encoding="UTF-8"?>
<routing-jssp-config
    xmlns="http://www.intra-mart.jp/router/routing-jssp-config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.intra-mart.jp/router/routing-jssp-config routing-jssp-config.xsd ">

    <authz-default mapper="welcome-all"></authz-default>
    <file-mapping path="/im_cookbook/113159/CSRF" page="im_cookbook_113159_CSRF/CSRF"></file-mapping>
    <file-mapping path="/im_cookbook/113159/CSRF2" page="im_cookbook_113159_CSRF/CSRF2"></file-mapping>
</routing-jssp-config>

「2. 遷移後の画面を作成してください。」で作成した各画面のルーティングを設定しています。

4. セキュア・トークンフィルタ設定ファイルを作成してください。

e Builder のモジュールプロジェクト内に以下のxmlファイルを作成してください。
src/main/conf/token-filtering-target-config/im_cookbook_113159_CSRF.xml

<?xml version="1.0" encoding="UTF-8"?>
<token-filtering-target-config
    xmlns="http://www.intra-mart.jp/secure-token/target-url-config"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.intra-mart.jp/secure-token/target-url-config ../../schema/token-filtering-target-config.xsd ">

    <entry url="/im_cookbook/113159/CSRF2"></entry>
</token-filtering-target-config>

セキュア・トークンフィルタ設定ファイルでURLを設定することで、アクセスされた時にセキュア・トークンを用いたリクエストの正当性の確認が実施されます。
<entry>タグのurl属性に、リクエストの正当性の確認を実施するURLを指定してください。
URLは完全一致となるように指定してください。

セキュア・トークンフィルタ設定ファイルの詳細は以下のドキュメントを参照してください。
設定ファイルリファレンス / セキュア・トークンフィルタ設定