2010年08月27日

掲示板CGIの削除キーは他人に簡単に見られるので注意

日本の個人サイトに多いログイン機構を持たない簡単な掲示板システムでは、後で記事を削除するためのパスワードを入力するものが多いですが、このパスワードをCookieに記憶しておいてCGI側でフォームに埋め込んで返すという仕組みはセキュリティ上の問題があります。

HTMLのフォームのパスワード入力欄は入力された文字が見えないようにマスクされていますが、この入力欄に初期値を与えようとすると、HTMLのソースにパスワードをそのまま書く必要があります。そのため、ブラウザで掲示板を開いた状態でそのページのソースコードを他人に見られてしまうと、パスワードがバレてしまいます。

次の例は、某サイトで配布されている掲示板CGIに、削除キーとして”pass”と入力して書きこんだ後の、CGIの返したHTMLの一部です。

<tr>
  <td nowrap><b>削除キー</b></td>
  <td>
    <input type="password" name="pwd" size="8" maxlength="8" value="pass">
	<small>(英数字で8文字以内)</small>
  </td>
</tr>

見ての通り、value=”pass”としっかり書かれています。

このように簡単に見ることができてしまうので、重要なアカウントに使用しているのと同じパスワードを簡易掲示板に入力するのは絶対にやめた方がいいです。

パスワードが漏れない実装を考える

このような問題に対して掲示板システムを作る側がどう対処すべきかを考えます。

日本ではユーザ登録不要の簡単な掲示板が好まれているので、ここではログイン処理やセッション管理をせずにパスワードの安全性を保つ方法を考えます。

JavaScriptでCookieを扱うと少しだけマシになる

CookieをCGIで処理するのではなく、JavaScriptを使って処理すると少しだけマシになります。ページを表示したときにJavaScriptでCookieを読み、動的にフォームを更新するようにすれば、HTMLのソースを見てもパスワードは分かりません。この程度の対策でも、何もしないのに比べれば、かなりマシになるでしょう。

この場合も、Cookieに保存するのは平文のパスワードではなく、少しは暗号化しておくべきです。例えばIE8なら[F12]を押せばCookieは丸見えなので、平文だと簡単に分かってしまいます。ただし、どんなに複雑なアルゴリズムを使用しても、暗号化ではセキュアになりません。暗号というのは復号する方法が隠されていないと意味がありませんが、CookieとJavaScriptではパズルの裏面に解法が書いてあるようなものです。ここでは、人間がぱっと見て分からなければ十分です。

この方法は気休め程度にしかなりませんが、既存のCGIからの修正が最小限で済むので、ちょっと対策をしたい場合に良いと思います。

真にセキュアな方法はパスワードを保持しない

一般的にパスワードの管理というのは、サーバ側で平文を保持するのではなく、ハッシュ値を保持しています。ハッシュ値とは平文から複雑な計算をして求めた数値で、暗号と似ていますが暗号とは違い元の値に戻すことができません。

例えばA=1,B=2,,,として、A+B+C+D+Eを計算すると15が得られますが、15からA+B+C+D+Eを導くことはできません。この場合は単純な計算なので15からA+B+C+D+Eを予想することは可能ですが、一般的に使用されるハッシュ関数は複雑なのでハッシュ値から元のデータを予想するのは事実上不可能となっています。

今回提案する方法は、フォームのパスワード欄にハッシュ値を使用します。

ユーザに直接ハッシュ値を書かせるのは無理なので、パスワード入力欄とは別に不可視フィールドに同じハッシュ値を設定しておき、掲示板システムが受け取ったパラメータを比較して両者が等しければハッシュ値、そうでなければ(=ユーザが編集した)平文と判定します。

パスワードとして平文を受け取った場合は、それをハッシュ関数に渡します。ハッシュ値を受け取ったときは、そのまま使用します。次回からフォームの初期値にはハッシュ値をセットします。Cookieに保存するのも、このハッシュ値とします。

パスワードを変更した際の書き込みアクセスではHTTPで平文でパスワードが流れますが、2回目以降はハッシュ値となるので、盗聴に対する安全性も上がります。初回の盗聴まで気にするなら、ハッシュ化をJavaScriptで行うのも良いでしょう。(ただしJavaScriptには組み込みのハッシュ関数が用意されていない)

注意するのは、削除用のフォームではパスワードを記憶しないこと、JavaScriptによるハッシュ化をする場合は削除用フォームでは使わないことです。削除用フォームでも同じようにハッシュ値での入力を受け付けてしまうと、ハッシュ値が分かるだけで削除できてしまうので意味がありません。

また、この手法は掲示板の削除キーくらいにしか使えません。パスワード確認というのは、ユーザに権限を与える際に使用しますが、今回の題材としている簡易掲示板では権限を行使するのは記事の編集/削除くらいで、その際にはパスワードの入力を求めています。ログイン処理やセッション管理が必要となるような処理の代用にはなりません。

タグ:Webサービス
2010年08月27日 【プログラミング】 | コメント(2) |

この記事へのトラックバック
この記事へのコメント

この話は、掲示板以外でも似たような問題があります。
例えばBUFFALOの無線LANルータはブラウザから設定を行いますが、WEPキーの設定欄などはHTMLのソースを見れば簡単に分かってしまいます。
その設定画面にアクセスするまでにパスワード認証があるので、基本的には問題ありませんが。

フォームの初期値をHTMLにそのまま書かざるを得ない問題は、パスワード以外の部分でもたまに悩まされます。
JavaScriptが使えない環境を切り捨てれば、もっと自由にできますが。
Posted by 新坂 at 2010年08月27日

簡易掲示板に限らず、簡易なCGIだとパスワードをCookieに保存して再利用するタイプ結構ありますよね。
Cookieってローカルでアクセスされたらまったくの無力なのに。。。

きっとこれはCGI作者側の意識の問題なんでしょうね。
だから type="password" のように中途半端にセキュア感を出してしまって、本当の危険。。。
キャッシュカードの暗証番号なんかが入力されてしまう危険とかを意識していない。
危惧されている問題は既に起きているかもしれません。悲しいことですが。

簡易なCGIに対しては「真にセキュアな方法はパスワードを保持しない」を私は支持します。
削除キーなら(ダウンロードキーなどと違って)他人に伝える必要もないでしょうし、パスワード入力すら不要とする作りが可能かも。
初回書き込み時にキーを自動生成するとか。。。
Posted by おにぎり at 2010年09月04日

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。