例外処理では「サニタイズ」が有効な場合もあるこのエントリでは、脆弱性対処における例外処理について、奥一穂氏(@kazuho)との会話から私が学んだことを共有いたします。セキュアプログラミングの心得として、異常が起これば直ちにプログラムを終了することが推奨される場合がありますが、必ずしもそうではないというのが結論です。はじめにWebアプリケーションの脆弱性対策では、脆弱性が発生するのはデータを使うところであるので、データを使う際の適切なエスケープ処理などで対処するのがよいと言われます。処理内容によってはエスケープができない場合もあり、その場合の対処についてはまだ定説がないと考えます。エスケープができない場合の例としては、以下があります。SQLの数値リテラルを構成する際に、入力に数値以外の文字が入っていたメール送信しようとしたが、メールアドレスに改行文字が入っていた入力されたURLにリダイレクトしようとしたところ、URLに改行が入っていたこれらの場合、エスケープはできないので、以下のいずれかの対処をすることになります。バリデーション:受け付けられない文字があった場合はエラーとして処理を終了するサニタイズ:受け付けられない文字を削除するか、他の文字に置き換えて処理を継続するここで前提として、入力値のバリデーションはしているのだが、何らかの原因でバリデーション処理に漏れがあって、そのデータを使う(たとえばメール送信)際に、上記が分かったというシナリオです。本来上記のような異常値は来ない前提だが、セーフティネットとして、処理の段階で対処をしておくということです。私は従来、このような場合はバリデーションがよいと考えていました。サニタイズは入力値を改変することになるので、いかなる場合でも好ましくないと考えていました。セキュリティ対策が確実に実施されない2つの理由」に関連して、大垣さんの寄稿に肯定的なコメントとして、facebookで以下の投稿をしました。出力時のバリデーションが必要な局面は確かにあって、(1)(好ましくはないが)SQLを動的に組み立てる際に、数値パラメータに数値以外の文字がある場合、(2)メール送信時に、メールアドレスや件名に改行が含まれていた、ようなケース。(2)のケースは、メール送信用のラッパー関数を作って改行やメールアドレスの改行チェックをするとよい。本来は入力時のバリデーションで弾かれているはず(べき)だが、万一漏れていた場合の安全装置として出力時のバリデーションも組み込んでおくと効率よく安全性を高めることができるこれに対して、奥一穂氏から以下のコメントを頂戴しました。安全装置なら処理を停止よりはサニタイズすべきなのかなと思ったりします。(ry私はこの「事件」の詳細を知らないのですが、以下の現象だったと憶測しています。某Twitterライクなサービスはtwitterのように、フォローしている利用者のつぶやきが時系列的に表示されるユーザのH氏が誤って(?)不正なUTF-8シーケンスを含むツイートを投稿したそのつぶやきは入力時のバリデーションを通過してDBに格納されたそのつぶやきを表示する際に、不正UTF-8シーケンスが含まれているため、例外が発生した例外処理の結果、当該のツイート以降空となり、多くのユーザのタイムラインが影響を受けたH氏が、自身の不正なツイートで不利益を受けるのは仕方ありませんが、他のユーザにまで影響が及ぶことは問題です。入力時のバリデーション不備が根本原因ではありますが、フェールセーフのつもりの例外処理があだとなって、影響が大きくなってしまいました。奥氏のコメントの意図は上記のようなものでしょう。これに対する私のコメントと奥氏のリプライ。