ikepyonのだめ人間日記

セキュリティに関することを書いていく予定。

Hiddenを使う必要のあるアプリケーション

昨日の日記にHiddenを使って、値をページ間で受け渡しするのは「シーラカンスなアプリケーション」と書いたけれど、実際のところ、どうしてもHiddenを使用しなければならないケースというのが存在する。それは、多くの場合、たぶん以下の4つ(もしかしたら1と2はひとつと考えてもよいかもしれない)のケースぐらいかと思う(もっとあるかもしれないけどいまいち浮かばん)。

  1. Cookieを使用できない場合(携帯アプリのようなケースが上げられる)、セッションIDをHiddenで受け渡すケース
  2. CSRF対策としてワンタイムトークンの格納場所として使用するケース
  3. 以前のページでユーザから受け取ったデータをJavascript内で使用したいケース
  4. 指摘のあったボタンなどで機能などを選択するケース

これら4つ以外のケースでページ間のデータをやり取りするような場合(Hiddenをあたかもグローバル変数のように使うときとか、例えが悪いかも)には、Hiddenを使用するしかないが、それ以外の場合はセッション変数を使用することで対応できることが多いと思う。
1のケースでは、HTTPがステートレスなプロトコルであるため、現在のセッションの状態を把握するためのセッションIDがWebアプリでは必要となるため、CookieかHiddenというユーザが一見すると操作できない箇所にセッションIDを格納しなければならないため、Cookieが使用できないとなるとHiddenを使用するほかなく仕方がない。
2のケースでは、グダグダここで書くより、金床さんのhttp://www.jumperz.net/texts/csrf.htmを見てもらったほうが早いw
で、問題の3のケースだけれど、これはJavascript内での入力データのエスケープ処理の複雑さに由来する。Javascript内で入力データを使用したい場合、XSSが発生しないように、エスケープ処理するのは、Scriptに埋め込む箇所に依存して、方法がさまざまなので、非常に困難である。しかし、Script内で入力データを使用したい場合、方法が確立しているHTMLのエスケープ処理で対応できるHiddenをScript内から参照するほうが楽である。したがって、このようなケースの場合はHiddenを使用することが望ましい。
4のケースは言わなくても当たり前ということで。でもこのケースも仕様を変えれば案外対策できたりするけど…どうしてもHiddenを使わなきゃいけないって物でもない気もするなぁ。まあ、仕様としてこうだといわれりゃしかたがないけど。
これら以外のケースでページ間で入力されたデータの受け渡しをする際にはセッション変数を使用するほうが楽だろうし、安全だろう。
とはいえ、複数のサーバで負荷分散しなくてはならないケースとか、処理が複数のサーバに渡るケースなどではそうは言ってられないのだろうけど…
そういったケースでも安全に使用する方法をちと暇なときでも考えてみよう。

(追記)指摘があったので、いろいろ加筆修正。

内容にはいろいろ問題あるのでまだまだ検討中の話ということで・・・