2013年3月20日水曜日

プログラム実行系のセキュリティホールに関しての解説

Webセキュリティはもはや収束点ができているのに、まだ誤解が伝授されているケースがある。

ここではそれを正す。

Webセキュリティで結構アウトなのは「プログラムを実行される」ということ




  • SQLインジェクション
    • 外部からSQLを実行される。つまりデータベースを外部の人間が操作できてしまう
  • コマンドインジェクション
    • 外部からサーバ上のコマンドを実行されてしまう
  • ディレクトリトラバーサル
    • 外部から見えてはいけないファイルを見られてしまう
  • クロスサイトスクリプティング
    • 外部からWebページの中にJavaScriptを埋め込めてしまう
いずれも、システムそのものを変更されてしまう。外部から入ってくるデータは単なるデータなのだから、プログラムに変わってしまうケースなんて必要無いのだが、それでも動いてしまうケースはある。その穴を埋めるのがセキュリティ対策。

サニタイズという言葉が出てくる時点で人としてヤバイ

サニタイズ(無害化)という言葉がある。外から入ってくるデータを全部無害かしちゃえばいいじゃないという発想。SQLっぽい文字が入ってきたらその文字をいれさせなければいい。酷いケースだと半角文字が入ってきたら全角に変換すればいいじゃないって人もいる。それも一つの対応だろうけど、半角文字が必要なケースはどうする?機能が低下しちゃってるじゃない。セキュリティと利便性はトレードオフかも知れんが、上記のセキュリティホールに関しては、機能を全く低下させることなく穴をふさぐことは100%できる。

「サニタイズ言うな」という検索ワードが候補として出てくる。サニタイズカルチャーは、知識が少なかった頃の名残。

穴によって対策は違う

セキュリティの基本は「直前に操作対象に応じたエスケープ」が正解。データタベースに渡す文字列なのか、ブラウザに渡す文字列なのかよって、実行されちゃうプログラムは別だから。
  • SQLインジェクション対策
    • データベース操作の直前に、外部からのデータをデータとして扱えるようにエスケープする。
    • ほとんどのデータベース操作ライブラリには「プレースホルダ」という仕組みがあって、素直にそれを使えば、外部データがSQLに変わってしまうことなんてない
    • プレースホルダはデータにしか使えないが、外部からプログラムの文字列を構築すること自体があってはならない
  • コマンドインジェクション
    • コマンドを外部から自由に使うということは要件としてあり得ないので、コマンド文字列は内部で構築する
  • ディレクトリトラバーサル
    • ファイル名だけもらうべきところを、ディレクトリまで通しちゃうから穴になる。
    • ファイル名だけを取り出し、さらに見せてもいいファイルかどうかをチェックすればいい
  • クロスサイトスクリプティング
    • htmlタグをユーザが作れてしまうという構造がおかしい。ほとんどのWebフレームワーク二はhtmlにテキストを出力する際のエスケープ関数が用意されているからそれを使う
    • 大事なのは、HTMLを出力する直前ということ。

関数やキーワードとしてはこんなの
  • SQLインジェクション対策
    • mysqli_real_escape_string
    • プレースホルダ
    • バインドパラメータ
    • プリペアドステートメント(プレースホルダとセットで)
  • ディレクトリトラバーサル対策
    • basename
  • クロスサイトスクリプティング
    • htmlspecialchars

そもそもセキュリティホールがあるアプリは通常にも機能しない

  • SQLインジェクション脆弱性があるデータベースは、「L'Arc-en-Ciel」がまともに検索できない。
  • クロスサイトスクリプティング脆弱性のある掲示板は、htmlの書き方をやりとりすることができない
つまり、コマンド実行系セキュリティホールは完全に閉じた上で利便性も生産性も損なうことなんてない。

0 件のコメント:

コメントを投稿