よい子のための hidden 講座2006年04月12日 09時05分49秒

hiddenって、何?

(X)HTML におけるフォーム要素の一種です。ブラウザ上には表示させずに、ページに任意の値を埋め込むことができます。例えば以下のように使います。

<form action="diary.cgi" method="post">
  タイトル:
  <input type="text" name="subject" size="40"><br>
  日付:
  <input type="text" name="date-y" value="2000" size="8" maxlength="4">年
  <input type="text" name="date-m" value="4" size="4" maxlength="2">月
  <input type="text" name="date-d" value="12" size="4" maxlength="2">日<br>
  本文:<br>
  <textarea cols="60" rows="10" wrap="soft"></textarea><br>
  
  <input type="hidden" name="real-date" value="1144802196">
  <input type="hidden" name="session"
  value="89f016e7e6e59426e68c0eea9bc353f9">
  
  <input type="submit" value="書き込む">
</form>

表示上では以下のように表示されますが、

タイトル:
日付:
本文:

実際には、こうして表示される項目に加えて、以下の名前と値の組み合わせが、このページの中に埋め込まれているわけです。

名前意味
real-date 1144802196 このフォームを表示するときのサーバーの時刻を表す値。日本時間で 2006/4/12 09:36:36
session 89f016e7e6e59426e68c0eea9bc353f9 セッション ID。通常は予測困難な値にするだろう、っちゅーことで、このサンプルでは適当な文字列を MD5 してみた。

どんなときに使うもの?

ユーザーが CGI に対して送信しなければいけない値のうち、ユーザー自身に手入力させたくない値で、なおかつ表示する必要のない値を、あらかじめフォームに含めておきたいときに使います。先ほどの例の場合、表示に使われる日記の日付はユーザーが自由に設定できるよう、入力欄を設けていますが、実際にその日記を書き始めた日時 (これは CGI プログラムが記事を整理したり、日記を書くのにかかった時間を把握する必要がある場合などに使う値という想定です) はユーザーに書き換えられても嬉しくないし (困る、というほどのものではない)、わざわざ表示するような情報でもないので、hidden として埋め込んでいます。

使ってはいけない場面って?

hidden は (X)HTML のフォームの一部に過ぎません。ブラウザ上では表示されませんが、ソースを閲覧することは容易です。また、フォームはユーザーが手元で自作することもできるため、意図しない値に書き換えられる可能性が十分にあります。

1. ユーザーに見られたくない値

例えば、hidden フィールドにパスワードを入れておき、入力されたパスワードと、hidden の値を比較して認証を行う、という使い方は NG です。

<form action="autholi.cgi" method="post">
  パスワード:
  <input type="password" name="subject" size="40"><br>
  
  <input type="hidden" name="pwd" value="oppaidaisuki">
  
  <input type="submit" value="部屋に入る">
</form>

「ソースを表示」でパスワードを確認。誰でも入れる認証ページ。これぞ開かれたインターネット。すばらしい。

信じられないかもしれないけど、昔はこーいう間抜けなインターネット、意外と多かったのよw。

2. 書き換えられると非常に困る値

ショッピングサイトとかで安易に hidden 使いまくっちゃうと、ユーザーにちゃっかり決算を安く見積もられちゃうかもしれません。

<table frame="border">
  <tr>
    <th>商品名</th>
    <th>単価</th>
    <th>数量</th>
    <th>価格</th>
  </tr>
  <tr>
    <td>テレビ</td>
    <td>200,000</td>
    <td>1</td>
    <td>200,000</td>
  </tr>
  <tr>
    <td>テレビ台</td>
    <td>50,000</td>
    <td>1</td>
    <td>50,000</td>
  </tr>
  <tr>
    <td>HDD/DVD レコーダー</td>
    <td>100,000</td>
    <td>1</td>
    <td>100,000</td>
  </tr>
  <tr>
    <td>DVD-R 10枚パック</td>
    <td>10,000</td>
    <td>2</td>
    <td>20,000</td>
  </tr>
  <tr>
    <th>合計</th>
    <td colspan="3">370,000 円</td>
  </tr>
</table>

<form action="kessan.cgi" method="post">
  この内容でよろしければ、「確認」を押してください。<br>
  <input type="submit" value="確認">
  
  <input type="hidden" name="transaction"
  value="e355bcacf56d8edf3735ab8f18f371cc">
  <input type="hidden" name="itemlist"
  value="tv 1 kagu 1 hdddvdrec 1 media-dvdr10 2">
  <input type="hidden" name="price" value="370000">
</form>

上記のコード例では、hidden にトランザクション ID (いわゆるワンタイム・トークン)、商品リスト、そして合計金額を埋め込んでいます。

トランザクション ID は、おそらくこの場面では必要なものでしょう。商品リストはトランザクション ID に関連付けられてサーバー側で管理されているべきなので、本来ならば不要ですが、それでも一応許容範囲内です。なぜならこれを書き換えられても、購入したい商品が変更になるだけで、どちらかが損をすることはないからです。

しかし合計金額を hidden に埋め込むのは NG です。ユーザーはこのフォームの HTML を保存し、テキストエディタでこの hidden の値を書き換え、それをブラウザで表示して、「確認」ボタンを押すかもしれません。その場合、これらの商品がたったの 1円で決算されてしまうかもしれないのです。

3. 経路上を流れてはまずい情報

HTTP による通信は、通常平文で行われます。平文で流れる情報は、通信経路となるホストを管理する人間に閲覧される可能性があります。SSL によって通信自体を暗号化してしまえば、閲覧される可能性はほとんどなくなりますが、SSL を使用できない環境の場合、閲覧されてはまずい情報自体を通信に乗せないようにする必要があります。

では、その場合、どうするべきなのでしょうか?

答えは、「閲覧されたくない情報は、どのような手段であれ、通信に流してはいけない」です。これは、hidden フィールドはもちろんのこと、クッキーだろうが基本認証だろうが結局は同じことです。

SSL による暗号化が使用できない環境では、すべての通信内容が常に第三者に傍受される可能性があります。これは防ぎようのないことなのです。セッション ID の漏洩は困るかもしれませんが、hidden に置こうがクッキーに置こうが、漏れるときは漏れるんです。セッション ID を再度暗号化したところで同じです。結局「一意の値」であることに変わりはないのです。

hidden フィールドが漏洩することって、あるの?

Web アプリを使用するユーザーや場面に応じて変化する値が、想定しないユーザーに勝手に閲覧される可能性については、Web アプリ自体やブラウザなどに特別な欠陥でもない限り、起こり得ないと想定すべきです (経路上での傍受の可能性については考慮しないものとして)。少なくとも、「クッキーよりも危険」ということはありません。

コメント

_ @DRK ― 2006/04/13 00:21:09

セキュリティは難しいねぇ。素人はまずプロの言う事を聞いた方が良さそうだ。

あと、例文のパスワードはどこの板やw

_ 64bit ― 2006/04/13 15:23:49

> 表示上では以下のように表示されますが、

反射的にサンプルフォームに入力して,「書き込む」をクリックしたら請求書や督促状が送られてくるのかと思いましたが,そうではないですね.良かった良かった.

_ T.MURACHI ― 2006/04/13 23:41:05

>@DRK
を、よく読んでるねぇ。突っ込み㌧クスwww
まぁ、別にどこかの板を指してるわけでもないんだけどね。

>64bit
を、おひさっす。まだ生きてたか、よかったよかった。(←失敬)
ちなみに、最初、サンプルフォームのボタンを <input type="submit"> のまんまにしていて、本当にどこかに何かを送信しようとするボタンになっちゃっていた状態で数分ほど公開しちゃっていたのはひみちゅw (今は単なるボタン <input type="button"> っす^_^;)

_ @DRK ― 2006/04/14 11:48:19

というか”絶対おみゃーさんの発言じゃないわ”というところが・・・
むしろvalue="binyuudaisuki"では?wwwww

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
おいらがやっている会社の名前をひらがな4文字で。

コメント:

トラックバック

このエントリのトラックバックURL: http://harapeko.asablo.jp/blog/2006/04/12/324556/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。