@kyanny's blog

My life. Opinions are my own.

4. Webアプリケーションの機能別に見るセキュリティバグ (4.4 SQL 呼び出しに伴う脆弱性)

ハイライト二つ目。 SQL インジェクション。 4.3 XSS をまとめるのにずいぶん時間がかかったので時間あけて二度読みなおした。

  • SQL インジェクション(影響範囲とか危険性はいうまでもない)
    • エラーメッセージ経由の情報漏洩
      • cast() をつかって型不一致でエラーメッセージで id, password が漏洩
    • UNION SELECT で情報漏洩
    • SQL インジェクションで認証回避(よくある例)
' or 'a'='a

WHERE id = '$id'

WHERE id = '' or 'a'='a'
    • SQL インジェクションによるデータ改ざん
';update books set title='<i>cracked!</i>' where id='1001'--

WHERE author = '$author' ORDER BY id

WHERE author = ''; update books set title='<i>cracked!</i>' where id ='1001'--'ORDER BY id
      • -- 以下はコメントアウトされる
    • その他の攻撃(OS コマンド実行、ファイルの読み出し書き込み、 HTTP リクエストで外部サーバ呼び出し)
    • information_schema でテーブル名と列名を調べる手法
  • 脆弱性が生まれる原因
    • 開発者の意図しない形に SQL 文が改変される
    • リテラルの扱いが不適切なのが原因
      • 文字列リテラルのエスケープ漏れ(シングルクォート)
      • 数値リテラル(シングルクォートで囲まないので ; 以下に SQL 文を挿入される)
  • 対策
    • プレースホルダ ?
    • 静的プレースホルダ
      • 値のバインドをデータベースエンジン側で行う
      • プレースホルダの状態で SQL 文がコンパイルされる (確定) ので原理的に変更されない -> 安全!
    • 動的プレースホルダ
      • SQL 呼び出しアプリケーションのライブラリが値を適切にエスケープしてバインドした SQL 文を渡す
  • LIKE とワイルドカード(SQL インジェクション脆弱性ではない)
  • ソート列名と SQL インジェクション
    • ソート列名として適切なカラム名のホワイトリストを保持して一致するかチェックする
  • SQL インジェクションの保険的対策
    • エラーメッセージを表示しない(ログファイルに吐く)
    • 入力値のバリデーション(記号をはじく)
    • データベースの権限設定(読み出しのみ)
  • まとめ
    • 常に静的プレースホルダを使う(例外を設けない!)