Tweet

冬休み

サニタイズ

というあたりについて,つらつらと考えてみる.

サニタイズとは,web ブラウザからの入力値を別のプログラムへ渡す際にその入力値のチェックを行うこと,である. 入力値チェックの重要性は古くから知られており,私の場合はCERT® Advisory CA-1997-07 Vulnerability in the httpd nph-test-cgi script で,この問題の存在を知ったのである. apache の前身である NCSA httpd に付属していたサンプル CGI に問題があったわけで,実にそういう大昔から連綿と続く話なのである.

perl では,この問題に対して「taint(汚染)」という概念で対処している. これも赤ラクダ本の時代から perl に備わっている機能であり,歴史は古い. perl4 の時代は taintperl いう perl インタプリタでこの機能が有効になる. 現在は perl -T,だったかな. で,その機能は

  • プログラム外部から来た文字列には「taint」フラグがセットされる
  • このフラグは,サニタイズしてくれなさそうな文字列演算では伝搬する
  • このフラグは,s/// 演算子などのサニタイズ効果のある演算子でクリアされる
  • そして,このフラグが付いた変数を引数として eval や system などの,攻撃対象になりそうなコマンドは実行できない.

といったところである. このような「taint」機能は,perl だけではなく ruby などにも実装されている.

が,現実問題,不正な(攻撃を意図した)文字列による web の脆弱性のニュースは後を絶たない. 何が問題なのだろうか.

そもそも,taint メカニズムは,脆弱性の一部は発見してくれるが,必ずしも「全部」は発見してくれない. たとえば s/// 演算子で taint フラグはクリアされるが,置換文字列を設定するのはプログラマ自身である. ここで不完全なサニタイズが行われる可能性がある. また,一言で「サニタイズ」と言っても,どの文字がメタ文字となるかは,ターゲット言語によって異なる.

というわけで,なにか「必殺技」みたいなものは実装できないのかな,と考えるのだけど… うーむ. これがなかなか難しそうな気がする.

たとえば,以下のようなクラスを考えてみる.

  • インスタンス変数は文字列と多数の tainted フラグ
  • tainted フラグは各言語(HTML や sh など)に対して存在する
  • HTML や sh などの言語は pluggable で,追加可能
  • (各言語に対応した)サニタイズメソッドを通過したインスタンスに対しては tainted フラグがクリアされる

が,これを perl 上で実装した場合を考えてみると,たとえば split とかのビルトイン関数の呼び出しで苦労しそうな気がする. ここらもメソッドとして再定義してやればいいのだろうけど,あまり使い勝手の良さそうなものにならないような気がする.

ruby あたりではもう少しマシかもしれないけれど…


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2005-12-31 (土) 00:44:32 (4582d)