変数展開したSQLは常にインジェクションが発生すると思い込もう

変数展開したSQLは常にインジェクションが発生すると思い込もう

  • こういうコードを見ると不安になります
  • PHPでかつ、Laravelであると想定します
$foo = SomeModel::select("select * from some_table where some_column = {$condition}");

何がよくないのか?

  • $orderにインジェクション可能なSQLがユーザ入力で指定された場合に大切なデータが全て消え去ります
  • 特にテーブル名をそのままレスポンスに含めていると、簡単にDELETE文の対象にされてしまいます

どうすればよかったか?

  • プレースホルダを必ず用いる様にしましょう
  • プレースホルダを用いることが出来ない場合は少なくともSQLと想定される文字列をエスケープできる様にしましょう
  • 上記の例であれば下記の様なコードに置き換えるだけでインジェクションの脅威はなくなります
$foo = SomeModel::select('select * from some_table where some_column = ?'. [$condition]);

伝えたいこと

  • SQLを発行するコードを際は常にSQLインジェクションが発生しないコードを書きましょう
  • 最もコストが低く、簡単にインジェクションを許さない方法はプレースホルダを検討することです
  • また、プレースホルダが利用できないのであれば最低でもSQLとみなされそうな文字列はエスケープしましょう
  • テーブル名をレスポンスに含めている場合は攻撃者に攻撃するための情報を与えている様なものです
  • 簡単に攻撃を許さない様に細心の注意を払いましょう