tokuhirom's Blog

Amon2とJSONとセキュリティ

あたりをよんで、JSON とセキュリティについてかんがえてみた。

ここで、有効とされている対策のうち

といったあたりは、RESTful でないし、BK 感がひどいというか本質的ではないのでできるだけやりたくない。


また、Amon2 では互換性をできるだけこわしたくない、という理由からもこのあたりの対策をとりづらい。

そこで、そういったあたりをさけて対策をかんがえる。

ブラウザでの JSON 直接表示にたいする対策

  • '<'
  • '>'
  • '+'

あたりを \uXXXX な形式にするエスケープが有効なのでこれはやっておく。ねんのため X-Content-Type: nosniff ヘッダも付与しておく。

これはだいぶ前に実装済である。

JSON hijacking にたいする対策

Firefox 3.0.x 以下では __defineSetter__ がつかえるため、scriptタグでよみこまれたときにデータをぬすまれる可能性があった。しかし、firefox 3.0.x はサポートが終了しているし、その後のバージョンではこの問題は修正されている。またこれにかんしてはブラウザの問題であるとして処理されているので、ウェブアプリケーション開発者が対処する必要はないといえる。

[4] の Array Constructor をもちいた攻撃については最新の firefox では再現しなかった。

一方で、[1] によると Android のブラウザでは JSON hijacking がまだ有効なようである。Android のユーザーはブラウザのアップデートを怠ることがおおいということからも、とりいそぎこちらは対応しておくことがのぞましい。

ここで対策としては

  • X-Requested-With のあるリクエストのみを許可する
  • POST のみを許可する

といったあたりがかんがえられるが、

  • ブラウザ以外のスクリプトなどによるリクエストには X-Requested-With ヘッダは付与されていない
  • POST のみの付与は RESTful でないし、ウェブアプリケーションフレームワークレベルでいれる処理としては非互換性が大きすぎる

といった問題がある。

またそもそもがこの問題は基本的には「ブラウザの問題」であるから、最終的にはブラウザが悪い。

といった前提条件を加味して、Amon2::Plugin::Web::JSON では以下のような条件をみたした場合に 403 Forbiddden を発行して、ユーザーを保護することにした。

  • 「GET リクエストである」かつ
  • 「Cookie ヘッダを送信している」かつ
  • 「/android/i にマッチする User-Agent ヘッダを付与している」かつ
  • 「X-Requested-With ヘッダを付与していない」

のすべての条件をみたしている場合のみ 403 Forbidden をかえす。

これぐらい厳しい条件であれば誤爆する可能性はほぼないし、問題となるケースについては対策できているのではないかとおもう(未知の JSON hijacking があれば別だけれど)。

というわけで、こういう対策をした Amon2 3.29 がでました。

THANKS TO

本稿について助言をいただいた id:hasegawayosuke さんに感謝します。

【20111125 追記】
AND か OR かがわかりにくいという指摘を徳丸さんにいただいたので修正した。