SQLインジェクション は、Webアプリの入力値を通じてSQL文を不正に変化させ、データベースの参照、改ざん、削除、認証回避などを狙う攻撃手法です。
検索フォーム、ログインフォーム、管理画面、APIのパラメータなど、ユーザーが送った値をSQLに使う場所で問題になります。
まず押さえたいポイント
- 入力値をSQL文字列に直接連結すると起きやすい
- 顧客情報、注文情報、管理者アカウントなど重要なデータが狙われる
- プレースホルダやプリペアドステートメントが基本対策になる
- ORMやクエリビルダを使っていても、生SQLを組み立てる部分は注意が必要
- DBユーザーの権限が広すぎると被害が大きくなる
どんな場面で出てくる?
ログイン画面でメールアドレスやパスワードを照合する処理、商品検索、管理画面の絞り込み、CSV出力、レポート作成などで出てきます。
特に、急いで作った管理画面や、古いPHPコード、直接SQLを書いている処理では注意が必要です。
Laravelのようなフレームワークでは、Eloquentやクエリビルダを正しく使えば多くのSQLインジェクションを避けやすくなります。
ただし、DB::raw() のように生のSQLを扱う部分、外部入力をそのままSQL断片に混ぜる部分では、フレームワークを使っていても危険が残ります。
よくある誤解
「入力チェックをしているから安全」と考えるのは危険です。
入力チェックは大切ですが、SQLインジェクション対策の中心はSQLと値を分離して扱うことです。文字種制限だけで守ろうとすると、抜け漏れが出やすくなります。
また、WAFを入れれば完全に防げるわけでもありません。
WAFは怪しいリクエストを前段で減らす助けになりますが、アプリ側のSQLの組み立て方が危険なままだと根本対策にはなりません。
実務で見るポイント
SQLインジェクションを防ぐときは、プレースホルダを使っているか、外部入力をSQL断片として扱っていないか、DBユーザーに不要なDROPや管理者権限を与えていないかを確認します。
さらに、エラー画面にSQL文やテーブル名を出さないこと、ログに攻撃らしい入力が増えていないかを見ることも重要です。
初心者はまず、「SQLを文字列連結で作らない」「DB権限を最小限にする」「危険な生SQLをレビューする」の3点から覚えると実務に使いやすいです。