Nakajijapan

生きるのに必死です。

CSRF Protection for Rails and Backbone.js

欲求不満では内部でBackbone.jsを利用しているのですが、セキュリティ強化のためにCSRF対策を施しました。 Railsを利用しているときはCSRF用のtokenを発行しているのでそれをBackbone.jsで通信するさいに情報を負荷 して送信させるようにしました。

ちなみに以前はModelにtoJSONメソッドでtokenを付加させていたのですがPOST,PUTのみの対応だったので DELETE用にも対応できるよう実装してみた。(Model.destroy時にはtoJSON()を仲介しない)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#-------------------------------------------
# Sync
#-------------------------------------------
Backbone._sync = Backbone.sync
Backbone.sync = (method, model, options) ->
  if method == 'create' || method == 'update' || method == 'delete'
    options_csrf =
      headers:
        'X-CSRF-Token': BackboneFrustration.Model.csrf_token()

    _.extend(
      options,
      options_csrf
    )

  return Backbone._sync(method, model, options)

メソッドをオーバーライドしてHEADERにX−CSRF-Tokenを付加して親処理に渡す。BackboneFrustration.Model.csrf_token()は 単純にフォームからCSRF用のtokenを取得しているだけです。これでajax通信のときはtokenを無視して処理をするようなその場しのぎな実装をせずになりました。

以下のような処理撲滅です。

1
protect_from_forgery except: :craete

この修正で問題なく動作しているので適用させました。

ところでRails用のgemでbackbone-railsなんてものがありましてそこのコードを 見ていたらだいたい同じことをしていたのであらかじめこれを参考にして勉強すれば良かったと思いました。とほほ。。

https://github.com/codebrew/backbone-rails/blob/master/vendor/assets/javascripts/backbone_rails_sync.js

とりあえず、これで一安心。

実際の修正箇所

https://github.com/nakajijapan/frustrationme_app/pull/25/files