高木氏の「サニタイズせよと言うな」キャンペーンにも関わらず、前時代的な汚染チェックしましょう運動に廃れる気配がないのはなぜ?

 HTTPリクエストパラメータをサニタイズすればOKという「入り口を塞げば安全」の発想から生まれるのは、「チェック済みの値をDBに入れたのだから、DBに入っている値はノーチェックでいいはず」のような盲信の連鎖。(「$data = s/(.*)/$1/; # ここでは大丈夫なはず」のような) そんなものは、連携モジュールや連携プログラムが一つでもチェックを怠っていたり、前提に食い違いがあったりすればたちまち崩れ去る。

 データが汚染されていようがいまいが、HTML出力エンジンでは必要なエスケープ処理やタグ除去処理を行い、URIを受け取りリソースを取得するモジュールは与えられたURIの妥当性チェックを行い、DBアクセスするモジュールはすべての可変パラメータをエスケープし、printf系関数の書式文字列には固定文字列を使うなりきちんと実装したパーザとビルダで生成する。一歩進んでDoS対策については、処理にタイムアウトを設けるなり、事前にコスト見積(SQL処理ならEXPLAINなど)して、閾値で制御できるようにする。このように個々の部品レベルでやるべきことをやれば、入り口に穴があってもデータフローの途中に抜けがあっても影響は限定的だし、データに前提条件を課すことなくどこでも使える。

 そもそも、セキュリティということを抜きにしても、美しい設計という観点があれば、レイヤー違いの処理を強いる部品なんてものは作られ得ない。また、処理の負荷を考えても、バリデーションレイヤーでがんばるのには所詮無理がある。トランザクションに入らなければ捕捉できないエラーもあるのだから、バリデーションは明らかにおかしな入力を弾くものにとどめ、それ以上は実処理でのエラーで捉える方が現実的だろう。

 徹底して実践するのは楽ではないが、プロなら常に念頭に置いて努力しなければならないと思う。

 と、先日やっつけで書いたCのコードを堅牢な作りに書き直した直後の勢いでまくし立ててみました。実運用は緊張するよ!


Categories : Tech