「サニタイズ言うなキャンペーン」に癒されてみる2006年11月29日 11時15分15秒

言いだしっぺの高木先生お墨付き。一応、原典についてもリンクを示しておこうかしら。

てゆか、「やっぱりそれでいいんだよなぁ」と内心「ホッとした」というのが正直な感想。

思うんだが、「セキュリティー対策」と「セキュリティーホール対策」は、分けて考えるべきだと思う。

「セキュリティー対策」ってのは、その名の通り、セキュリティーを積極的に向上する為の対策であって、主な内容としてはウイルス対策ツールの導入だとか、プライベートファイヤーウォールの導入だとか (Unix 風 OS の常識から言えば、ポートフィルタリングは施していて当たり前とも思うが)、パッチを自動更新するだとか、バックアップを毎日取る ;-) だとか言ったような、ユーザーが (目的に応じて) 行う行動のことを指す。

「セキュリティーホール対策」ってのは、実態としては対策でもなんでもなくて、よーするに開発者が、欠陥のないプログラムを書くことを指す。積極的な対策の内容としては、せいぜい「ちゃんと勉強する」とか、「潜在要求の洗い出しをしっかりやる」とか、「よく考えて設計する」 (あるいは「レビューをしっかりやる」) とか、「ソースや文書の履歴管理をきっちりやる (cvs とか使って)」とか、「効率よくテストする」とか、「不具合管理を徹底する」とか、そんなところになるんではないかと思う。よーするに、ソフトウェア開発の現場に立つ人間であれば、誰でもやっているはずのことでしかない。

「サニタイズ」って言葉は、まるでプログラムが危険ゴミを見つけ出して一つ一つ取り除かなきゃいけないような印象を受ける。そもそも、そのデータ (の中の特定要素) が危険ゴミになるような場所に、危険ゴミが混入し得ないシステムとして設計されていれば、「サニタイズ」なんて意識する必要などないはずだ。

「でも、事実としてそういうシステムになっていないじゃないか」というのならば、その辺は自分でフォローすべきだと思う (ていうか、そうするしかないだろう)。たとえば、PHP で変数を HTML 出力するシーンでは、echo htmlspecialchars のラッパーを、俺様ライブラリとして用意すれば良いんではないかと思う。

<?php
define("HTML_CHARSET", "UTF-8");

function spill($text) {
    echo htmlspecialchars($text, ENT_COMPAT, HTML_CHARSET);
}
?>

で、実際の出力時はこんな感じで。

<table>
  <tr>
    <td>氏名</td>
    <td><?php spill($name); ?></td>
  </tr>
  <tr>
    <td>住所</td>
    <td><?php spill($address); ?></td>
  </tr>
  <tr>
    <td>電話番号</td>
    <td><?php spill($tel); ?></td>
  </tr>
  <tr>
    <td>メールアドレス</td>
    <td><?php spill($email); ?></td>
  </tr>
</table>

もっと複雑なケースではどうすべきか? って議論もあると思う。例えばユーザーの入力した HTML を部分的に許可したい場合とか、Wiki 文法を HTML 化したい場合とか。それらのケースでは、フィルタリング用のメソッドを設けて、そのメソッドの中で出力を行うようにすればいいと思う。あくまで、責任の所在は出力を生成する箇所であると決めてしまえば、設計上はすっきりするのではないかと思う。

<h2><?php spill($subject); ?></h2>
<div id="detail">
<?php
    $detail->filter();  // メソッドの中で、然るべき変換を行う
?>
</div>

こうやって詰めていけば、プログラムも設計も実にシンプルに考えることができるはずなのに、実際にはそんな単純じゃないんだーなどと勝手に思い込んじゃう人ってのは少なくないようで、その為に何だかかみ合わないやり取りが延々続くということはおいらも何度か経験があります。まさに、

ていうかこんな当たり前のことを改めて書かなくても、 という話だと思うのだが、どうもたとえば「PHPのmagic quoteはおかしい」 とか「ASP.NETのValidateRequestは本質的な対策になってない」とか言っても 通じない人に私はたまに会うし、高木さんに 「プログラミング解説書籍の脆弱性をどうするか」の記事で批判された 後藤さんの反論で、

htmlspecialchars() は、2重にかけるとおかしくなる関数です。リクエスト変数について「かけないこと」ほどは問題にならないものの、「かけすぎ」ればやはりおかしく表示されます。

こういう意見が出てくるのはいかがなものか、と私には思える (件の本は読んでないので、本そのものについて私は何も言えませんが)。

…というようなことが度々あって、しかもそういうことを言う人が、物凄く自身ありげに「俺様はこっち方面に詳しいんだぜ」ってオーラを醸し出してくれちゃったりされてしまうと、ビビリなおいらとしては微妙に自信なくなってしまう (とか言いながら自分で作るものについてはまったく気にも留めなかったりするわけですが)。

そういう意味では、この「サニタイズ言うなキャンペーン」はおいらにとってはとても癒されるキャンペーンであり、もっともっとこの輪が広がってくれることを願って止まないのであります。。。(;_;)/

ところで。。。

変だ変だと思いつつもそうした、というのには、 「PHPの郷に入ったら郷に従うべきなのかなあ」と思ったとか、 いくつか理由はあるのだが、やっぱりまずいと思うので注釈を追加しました。

個人的には、magic_quote_gpc が ON でも OFF でも良いように、以下のような入力用のラッパーを作ってあげるとよいのではないかと思っています。

function readPost($key) {
    return get_magic_quotes_gpc() ?
        stripslashes($_POST[$key]) :
        $_POST[$key];
}

しかしこんなことを強要する PHP って言語はつくづくアレだよなぁ。。。

なるほどね。2006年11月29日 23時25分55秒

つまり 03T = REMI だということはわかった。しかしまた厭な接点もっちまったもんだのう。

# このエントリは短期間で消滅するかも