1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

"Spring Boot" + "EXT JS"を使用したRESTアプリにおけるCSRF対策方針と実装例

Last updated at Posted at 2017-04-24

上記組み合わせでの情報が少なかったのでまとめました。

対策方針

CSRF(クロスサイトリクエスト偽造)対策としては、一般的なトークン発行方式としています。
サーバ→クライアントへのトークン情報の通知はSet-Cookieを利用するのが楽ですね。Spring Bootがやってくれるので。1
クライアント→サーバへのトークン送信はJavaScriptで独自に書いて、GETリクエスト以外2にCookie情報をhttpヘッダに書かせます。

  1. Spring Boot
    1.1. CSRFのトークンの保存先をCookieとする。
    1.2. JSからのアクセスを可能とするためにHttpOnlyとしない。
  2. Ext JS
    2.1. GETリクエストは対象外とする。
    2.1. ExtでのAjaxリクエスト送信時にCookie値からトークン情報を取得し、Httpヘッダに付与する。

実装例

Spring Boot

デフォルトでCSRF対策は有効ですが、トークンの保存先指定と、httpOnlyの無効化の定義をしています。

SecurityConfig.java

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            ...// 後略。適宜必要な定義を。
    }
}

Ext JS

Ajaxで飛ばす全てのリクエストにトークン付与が必要なので、上位に呼ばれる箇所で定義をしています。
"beforerequest"として定義することで、Ajaxリクエスト発行前に処理が行われるようにして、個別に実装しなくて良いようにしています。

app.js
Ext.Ajax.on('beforerequest', function (conn, request, eOpts) {
    // GETリクエスト以外の場合にCSRFトークンを付与する。
    if (request.method === 'GET') {
        return;
    }
    // CookieのXSRF-TOKEN項目値を、任意httpヘッダX-XSRF-TOKENとして付与する。
    if (document.cookie) {
        var cookies = document.cookie.split(";");
        for (var i = 0; i < cookies.length; i++) {
            var str = cookies[i].split("=");
            if (str[0] == 'XSRF-TOKEN') {
                conn.setDefaultHeaders({ 'X-XSRF-TOKEN': unescape(str[1]) });
                break;
            }
        }
    }
});
  1. (最初勘違いして)Cookieでトークン渡しても、セッションIDをCookieで持たせてる場合と同じでブラウザが勝手に送信してしまうので、CSRF対策として意味ないのでは?と思ったのですが、Spring BootでのCSRFトークンのチェックはCookie値を見ているのではなく、「formデータの_csrf」または「httpヘッダのX-XSRF-TOKEN」を見ているのがミソでした。トークンをCookieからformデータかhttpヘッダに置き換える必要がありますが、これをクロスオリジンなJSではできない(正規ドメインのCookieを見れない)ので対策となっているわけです。

  2. CSRF攻撃の特性を考えるとGETリクエストでは検証する必要ないですね。Spring Bootではサーバサイドチェックをしていません。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?