IT用語集

SQLインジェクションとは? わかりやすく10分で解説

水色の背景に六角形が2つあるイラスト 水色の背景に六角形が2つあるイラスト
アイキャッチ
目次

SQLインジェクションとは

SQLインジェクションとは、Webアプリケーションが受け取った入力値を不適切にSQL文へ組み込むことで、本来想定していないデータの参照・改ざん・削除を引き起こす攻撃です。対策の軸は明確で、最優先はプレースホルダ(パラメータ化クエリ)でSQLの構造と入力値を分離することにあります。加えて、入力値検証、WAF、権限分離、ログ設計を重ねると、被害の発生と拡大を抑えやすくなります。

この攻撃が厄介なのは、サイバー攻撃の中でもデータベースへ近い位置を直接狙うためです。個人情報、認証情報、取引データ、在庫、権限設定など、事業の中核にある情報が対象になりやすく、成立した場合の影響も大きくなりがちです。

なぜ今も対策対象から外せないのか

SQLインジェクションは古典的な攻撃手法ですが、過去の実装の残存、文字列連結の癖、周辺機能の追加、改修漏れなどが重なると、現在でも成立余地が生まれます。特に、検索、ログイン、会員情報参照、管理画面、外部連携機能など、外部入力を多く受ける画面では注意が要ります。

また、フォームの見た目が安全そうでも、攻撃者はURLパラメータ、Cookie、ヘッダ、JSONリクエストなどを直接編集できます。つまり、画面の制約に頼るのではなく、サーバ側実装で「入力値をSQL構文として扱わせない」状態を作る必要があります。

SQLインジェクションの基本

Webアプリケーションの多くは、利用者の操作に応じてデータベースへ問い合わせを行います。商品検索、ログイン認証、会員情報の参照、注文履歴の表示など、裏側でSQLが使われる場面は珍しくありません。

SQLとは何か

SQL(Structured Query Language)は、データベースのデータを操作するための言語です。代表的な操作には、検索(SELECT)、追加(INSERT)、更新(UPDATE)、削除(DELETE)があります。Webアプリケーションでは、利用者の入力や操作結果をもとに、こうしたSQLが組み立てられて実行されます。

なぜSQLインジェクションが成立するのか

成立条件は単純で、外部から来た入力値が、単なる値ではなくSQL文の一部として解釈されることです。例えば、検索条件やログイン条件を文字列連結で組み立てていると、入力内容しだいでSQLの意味そのものが変わる場合があります。

問題の本質は、危険な文字列が入ったことそのものではありません。入力値をSQL文の構造へ混ぜ込める実装に原因があります。そのため、禁止文字を増やすだけでは不十分で、構造と値を分離する設計へ変える必要があります。

どの機能で起こりやすいのか

  • ログイン機能:認証条件の組み立てに失敗すると認証回避につながる
  • 検索機能:検索キーワードが問い合わせ条件へ直接混ざりやすい
  • 管理画面:詳細検索や並び替え、絞り込み条件が複雑になりやすい
  • APIや外部連携:画面以外の入力経路で検証漏れが起こりやすい

SQLインジェクションの代表的な攻撃パターン

SQLインジェクションはひとつの形だけではありません。アプリケーションが何を返すか、エラーをどう扱うか、画面にどこまで表示するかによって、成立しやすい手口が変わります。

エラーベースSQLインジェクション

データベースやアプリケーションの詳細なエラーが画面へ出る場合、攻撃者はその内容からテーブル名、カラム名、問い合わせ構造などを推測しやすくなります。開発環境では便利でも、本番環境では情報収集の足がかりになりやすい類型です。

UNIONベースSQLインジェクション

検索結果などの出力へ別の問い合わせ結果を合成できる場合、想定外のデータが画面へ混ざることがあります。画面に表示される列数や型の制約は受けますが、条件がそろうと情報漏えいへ直結します。

ブラインドSQLインジェクション

ブラインドSQLインジェクションでは、データが画面へ直接出なくても、成功・失敗、表示有無、レスポンス差などを手がかりに情報を推測していきます。見た目には大きな異常が出ないこともあり、気づきにくい点が特徴です。

時間差ブラインドSQLインジェクション

時間差を使う手法では、特定条件が成立したときだけ応答時間が変わるような問い合わせを悪用し、画面の内容が同じでも内部情報を推測します。監視が甘いと「たまたま遅いアクセス」に見えやすく、追跡が難しくなる場合があります。

セカンドオーダーSQLインジェクション

入力直後には問題が表面化せず、保存済みデータが後続処理でSQLへ組み込まれた時点で影響が出るパターンもあります。プロフィール情報、メモ欄、CSV取り込み結果などが後から検索条件や更新条件に使われる設計では、この類型を見落としやすくなります。

SQLインジェクションが引き起こす被害

SQLインジェクションは、データベースに近い層へ影響を与えるため、漏えいだけでなく改ざんや停止にもつながります。代表的な被害は次の通りです。

  • 個人情報の漏えい:氏名、住所、連絡先、購買履歴など
  • 認証情報の漏えい:パスワードハッシュ、セッショントークン、APIキーなど
  • データ改ざん:価格、在庫、権限、プロフィール、管理情報など
  • データ削除:業務データ消失、サービス停止、復旧工数の増大
  • 二次被害:漏えい情報を使ったなりすまし、フィッシング、横展開攻撃など

企業側では、信用低下、問い合わせ対応、補償、調査、再発防止策の実装など、技術以外の負担も大きくなります。さらに、ログや監査証跡が不十分だと、どこまで見られたのか、何が改ざんされたのかを確定できず、対応範囲が広がりやすくなります。

SQLインジェクションを防ぐための対策

SQLインジェクション対策は、優先順位を誤らないことが重要です。最初に行うべきことは、アプリケーション実装で根本原因を断つことです。そのうえで、被害を抑えるための多層防御を重ねていきます。

プレースホルダ(パラメータ化クエリ)を最優先にする

最も重要な対策は、プレースホルダ(パラメータ化クエリ)を使うことです。SQL文の構造を先に固定し、入力値は後から値として渡します。これにより、入力値がSQL構文へ割り込む余地を減らせます。

言い換えると、SQLを文字列連結で組み立てないことが中核です。ORMやフレームワークを使っていても、手書きSQLや動的クエリ生成部分が残っていれば点検対象になります。

入力値検証は補助として使う

入力値検証も有効ですが、役割は補助です。数値IDは数値として受ける、日付は日付形式に限定する、並び順は許可済みの候補だけにする、といった制御は攻撃面の縮小に役立ちます。

ただし、入力値検証だけでSQLインジェクションを防ごうとすると、例外ケースや仕様変更で抜けが生まれやすくなります。基本はプレースホルダで構造を守り、入力値検証で想定外入力を減らす、という順番で考えるほうが安全です。

エスケープ単独対応へ依存しない

エスケープ処理は、文字列、数値、LIKE句、文字コード、データベース製品ごとの仕様差に左右されます。適用箇所を誤ると防御が崩れやすいため、単独の主対策として扱うのは危険です。

優先順位としては、プレースホルダ > 入力値検証 > 必要な箇所での適切なエスケープという並びで考えるほうが実装事故を減らしやすくなります。

最小特権の原則で被害範囲を狭める

万一SQLインジェクションが成立しても、被害を小さくしやすい設計が最小特権です。アプリケーションが使うデータベースアカウントには、必要最小限の参照・更新権限だけを与えます。

  • 参照専用機能は読み取り専用アカウントに分ける
  • 更新系と参照系で接続ユーザーを分離する
  • 不要な管理権限やDDL権限を与えない
  • 高権限処理は別系統へ切り分ける

この設計があると、攻撃成立時も「何でもできる」状態を避けやすくなります。

詳細エラーは画面へ出さず、調査用ログは残す

本番環境では、データベース由来の詳細エラーを利用者画面へ表示しない運用が基本です。一方で、運用側が追跡できない状態では、インシデント対応が遅れます。

そのため、次の分離が必要になります。

  • 画面:利用者へは最小限の失敗メッセージだけを返す
  • ログ:発生箇所、例外種別、リクエストID、呼び出し元などを記録して追跡可能にする

この構成なら、情報漏えいを抑えつつ、原因調査に必要な材料を残しやすくなります。

WAFは補助レイヤーとして使う

WAFは、既知パターンの検知や遮断、仮想パッチの適用、異常リクエストの観測といった面で役立ちます。ただし、アプリケーション側の根本対策を置き換えるものではありません。

文字列連結の脆弱な実装が残っていれば、回避や誤検知調整の問題が続きます。WAFは「導入したから終わり」ではなく、アプリ修正と併走しながら監視・調整する補助レイヤーとして位置づけるほうが現実的です。

開発と運用の両方で再発防止を組み込む

個別修正だけでは、別画面や別経路で同種の問題が再発しやすくなります。再発を抑えるには、作り方そのものへ安全策を組み込む必要があります。

  • セキュアコーディング規約で文字列連結SQLを禁止する
  • コードレビューで危険なクエリ生成箇所を重点確認する
  • 脆弱性診断を定期実施する
  • フレームワークや依存ライブラリを更新し続ける
  • 障害・攻撃検知後に追跡できるログ設計を整える

最初に点検したいポイント

SQLインジェクション対策を現場で進めるなら、次の順番で点検すると効率が落ちにくくなります。

  1. 文字列連結でSQLを作っている箇所の洗い出し
  2. ログイン、検索、管理画面、APIのような外部入力が多い機能の重点確認
  3. プレースホルダ化できていない動的条件の整理
  4. DBアカウント権限の棚卸し
  5. 本番エラー表示と調査ログの分離確認
  6. WAFルールと監視体制の見直し

特に、過去の改修で残った小さな検索機能や管理画面の絞り込み機能は見落としやすい箇所です。主要画面だけを直して終えると、別経路が残ることがあります。

まとめ

SQLインジェクションは、入力値がSQL構造へ混ざることで成立する攻撃です。防御の中核は、プレースホルダでSQLの構造と値を分離し、文字列連結SQLを排除することにあります。そのうえで、入力値検証、最小特権、ログ設計、WAF、継続的なレビューと診断を重ねると、成立確率と被害規模の両方を抑えやすくなります。

対策の優先順位を誤らなければ、SQLインジェクションは「手の打ちようが分からない脅威」ではありません。まずは、SQLをどこでどう組み立てているかを把握し、危険な文字列連結をパラメータ化へ置き換えるところから着手すると、改善の効果が出やすくなります。

FAQ

Q.SQLインジェクションはなぜ今でも問題になるのですか?

A.古い実装の残存、改修漏れ、管理画面やAPIの見落としなどで、入力値が文字列連結のままSQLへ混ざる箇所が残りやすいためです。

Q.一番優先すべき対策は何ですか?

A.プレースホルダ(パラメータ化クエリ)を徹底し、SQLの構造と入力値を分離することです。

Q.入力値検証だけで防げますか?

A.入力値検証は補助として有効ですが、単独では不十分です。構造と値の分離を先に行い、そのうえで形式チェックを重ねる考え方が安全です。

Q.エスケープ処理だけで対応してもよいですか?

A.単独対応へ依存するのは危険です。文脈やDB製品差で適切な扱いが変わるため、主対策はプレースホルダに置くほうが安定します。

Q.WAFを入れれば対策は完了しますか?

A.完了しません。WAFは検知・遮断の補助にはなりますが、アプリ側で危険なクエリ生成が残っていれば根本解決にはなりません。

Q.被害を小さくしやすい設計はありますか?

A.最小特権の原則が有効です。アプリ用DBアカウントに必要最小限の権限だけを与えると、成立時の影響範囲を狭めやすくなります。

Q.どの画面から優先して点検すべきですか?

A.ログイン、検索、管理画面、API、外部連携のように、外部入力を多く受けてSQL条件を組み立てる機能から着手すると効率が落ちにくくなります。

Q.詳細エラーを隠すだけで安全になりますか?

A.安全にはなりません。情報収集は難しくなりますが、脆弱な実装が残っていれば攻撃余地は続きます。画面の抑制と実装修正を分けて考える必要があります。

Q.ORMを使っていれば自動的に安全ですか?

A.自動的に安全とは限りません。手書きSQL、動的なクエリ組み立て、危険なAPI利用が残っていれば確認対象になります。

Q.継続的に行うべき運用は何ですか?

A.セキュアコーディング規約、コードレビュー、脆弱性診断、ログ監視、ライブラリ更新を継続し、個別修正で終わらせない運用へ乗せることです。

記事を書いた人

ソリトンシステムズ・マーケティングチーム