目次
SQLインジェクション攻撃(SQLi)とは、信頼できない入力によってデータベースクエリの構造や動作が変更される、Webアプリケーションへの攻撃です。
SQLインジェクション攻撃が成功すると、権限のないユーザーに機密情報を閲覧されたり、レコードを変更・削除されたり、認証を回避されたり、データベース管理操作を実行されたりするおそれがあります。
この脆弱性は通常、ユーザーが制御できるデータを、アプリケーションが動的に生成するSQLクエリへ直接連結した場合に発生します。主な対策には、パラメータ化クエリ、安全な開発プラクティス、最小権限の原則、アプリケーションセキュリティテストがあります。
Webアプリケーションファイアウォールは、疑わしいリクエストが脆弱なアプリケーションに到達する前に検知・遮断し、追加の保護層を提供します。
SQLインジェクションは、より広い「インジェクション」系脆弱性の一つです。OWASP Top 10:2025では、インジェクションがA05に分類されており、信頼できないデータをコマンドやクエリから常に分離することが推奨されています。
要点
- アプリケーションが信頼できない入力をSQLコマンドの一部として処理すると、SQLインジェクションが発生する可能性があります。
- 攻撃が成功すると、データベース情報の漏えい、改ざん、削除につながるおそれがあります。
- 主な種類は、インバンド型、ブラインド型、アウトオブバンド型の3つです。
- パラメータ化クエリは、最も重要な技術的対策です。
- 入力値の検証、最小権限、セキュリティテスト、WAFを組み合わせることで、保護をさらに強化できます。
- WAFは安全なアプリケーションコードを補完するものであり、その代替にはなりません。
SQLインジェクションとは?
SQL(Structured Query Language)は、アプリケーションがリレーショナルデータベースと通信するための言語です。アプリケーションはSQL文を使って、レコードの取得、データの作成、既存情報の更新、不要な情報の削除を行います。
たとえば、ECアプリケーションでは、商品の取得、顧客のログイン情報の確認、注文履歴の表示などにSQLが使われます。SQL自体は正当かつ不可欠な技術であり、データベースを利用するさまざまなアプリケーションで広く使用されています。
アプリケーションがSQL命令と信頼できない入力を安全でない方法で組み合わせると、SQLインジェクションのリスクが生じます。データベースが入力値を単なるデータとして扱わず、その一部を命令として解釈すると、本来のクエリロジックが変更される可能性があります。
OWASPのSQLインジェクション解説では、SQLインジェクションが成立する主な条件として、信頼できないデータがアプリケーションに入力されること、そしてそのデータがデータベースクエリの動的生成に使われることを挙げています。
関連用語を手早く確認したい場合は、CDNetworksのSQLインジェクションの用語解説をご覧ください。
SQLインジェクション攻撃の仕組み
一般的なSQLインジェクション攻撃は、次の4段階で進行します。
1. アプリケーションがユーザー入力を受け取る
入力元には、次のようなものがあります。
- ログインフォーム、登録フォーム
- 検索ボックス
- 商品ID、アカウントID
- URLパラメータ
- HTTPヘッダー、Cookie
- APIリクエストパラメータ
- JSON、XMLのリクエスト本文
ユーザー入力そのものが、直ちに脆弱性になるわけではありません。リスクは、アプリケーションが入力値をどのように処理するかによって決まります。
2. アプリケーションがSQLクエリを生成する
脆弱なアプリケーションでは、文字列連結によって入力値をSQL文へ直接組み込むことがあります。
たとえば、次の概念的なコードでは、SQLコマンドとユーザーが入力したメールアドレスを連結してクエリを生成しています。
email = request.getParameter("email")
query = "SELECT customer_id, name FROM customers
WHERE email = '" + email + "'"
database.execute(query)
アプリケーションは、入力値にメールアドレスだけが含まれると想定しています。しかし、その値がSQL文へ直接挿入されるため、想定外または悪意のある構文によって、本来のクエリ動作が変更される可能性があります。
OWASP SQL Injection Prevention Cheat Sheetでは、文字列連結とユーザー入力を使って動的クエリを生成することが、SQLインジェクションの一般的な原因だと説明しています。
3. データベースが改変されたクエリを実行する
アプリケーションは、完成したクエリをデータベースへ送信します。命令と入力値が明確に分離されていない場合、データベースは入力値の一部をSQL構文として解釈する可能性があります。
脆弱なクエリの内容や、アプリケーションのデータベースアカウントに付与された権限によっては、データベースがアプリケーションの許可範囲を超える情報を返したり、本来許可されていない操作を実行したりすることがあります。
4. アプリケーションが結果を露出する
考えられる結果には、次のようなものがあります。
- 認証の回避
- 権限のないデータベースレコードへのアクセス
- 技術的な詳細を含むデータベースエラーの表示
- 情報の変更、削除
- 通常とは異なるアプリケーションレスポンス
- ブラインドSQLインジェクションにおける応答遅延
情報が直接返される攻撃もあれば、アプリケーションの動作差からデータベースの応答を推測する攻撃もあります。
SQLインジェクション攻撃による影響
SQLインジェクションの影響は、脆弱なクエリ、データベース設定、アプリケーションのデータベースアカウントに付与された権限によって異なります。
機密情報の漏えい
攻撃者は、権限を持たないまま次のような情報へアクセスする可能性があります。
- 顧客情報
- 従業員記録
- アカウント情報
- 認証データ
- 社内業務データ
- 財務情報、取引情報
漏えいする情報の範囲は、クエリの対象範囲や、アプリケーションに付与されたデータベース権限に左右されます。
認証の回避
アプリケーションが安全でないデータベースクエリを使ってユーザー名とパスワードを確認している場合、攻撃者がクエリロジックを変更し、有効な認証情報なしでアカウントへアクセスする可能性があります。
業務データの改ざん
攻撃が成功すると、次のようなレコードが変更されるおそれがあります。
- アカウント情報
- 商品価格
- 在庫数
- ユーザー権限
- 取引内容
- 注文ステータス
- アプリケーション設定
不正な変更はデータの完全性を損ない、重要な業務プロセスに支障を与えます。
情報の削除
脆弱性によっては、攻撃者がレコード、テーブル、その他のデータベースオブジェクトを削除できる場合があります。その結果、サービス停止、データ損失、高額な復旧コストにつながる可能性があります。
データベース上の権限昇格
アプリケーションが過剰な権限を持つアカウントでデータベースへ接続している場合、SQLインジェクション攻撃に成功した攻撃者が、通常のアプリケーション運用には不要な管理機能へアクセスする可能性があります。
基盤システムへの影響
データベースやサーバーの構成によっては、SQLインジェクションがファイルアクセスやOSコマンドの実行につながる場合もあります。具体的なリスクは、データベース技術、有効化されている機能、データベースアカウントの権限によって異なります。
OWASP Web Security Testing Guideでは、SQLインジェクションによって、データ漏えい、データ改ざん、データベース管理操作、ファイルアクセスが発生し、条件によってはOSコマンドが実行される可能性もあると説明しています。
SQLインジェクション攻撃の種類
SQLインジェクション攻撃は通常、悪意のある入力を送信する方法と、情報が返される方法によって分類されます。主な種類には、インバンドSQLインジェクション、推論型またはブラインドSQLインジェクション、アウトオブバンドSQLインジェクションがあります。
インバンドSQLインジェクション
インバンドSQLインジェクションでは、悪意のある入力の送信とデータベース結果の受信に、同じ通信チャネルを使用します。
エラーベースSQLインジェクションは、詳細なデータベースエラーを利用する手法です。エラーから、テーブル名、カラム名、クエリ構造、データベースソフトウェアの種類などが漏れる可能性があります。
UNIONベースSQLインジェクションは、アプリケーション本来のクエリと別のクエリを結合し、権限のないデータをレスポンスに表示させようとする手法です。
詳細なエラー情報を非表示にすれば情報漏えいは減らせますが、脆弱なクエリ自体の修正は引き続き必要です。
推論型SQLインジェクションまたはブラインドSQLインジェクション
データベースの結果が直接表示されない場合、ブラインドSQLインジェクションが成立することがあります。攻撃者は、アプリケーションの動作の違いから情報を推測します。
ブールベースのブラインドSQLインジェクションは、データベース条件が真の場合と偽の場合で異なるアプリケーションレスポンスを利用します。
時間ベースのブラインドSQLインジェクションは、特定のデータベース条件によって生じる測定可能な応答遅延から情報を推測します。
OWASPのブラインドSQLインジェクション解説では、データベース出力が非表示でも、アプリケーションのレスポンスから情報が漏れる仕組みを説明しています。
アウトオブバンドSQLインジェクション
アウトオブバンドSQLインジェクションでは、データベースに外部ネットワークリクエストを発生させるなど、別の通信チャネルを通じて情報を送信します。
この手法が成立するかどうかは、特定のデータベース機能、システム構成、外向き通信の可否に依存します。
セカンドオーダーSQLインジェクション
セカンドオーダーSQLインジェクションは、安全でない入力がいったん保存され、その後、動的なクエリ生成に使用されることで発生します。
最初のリクエストには問題がないように見える場合があります。その後、別のアプリケーション処理が保存済みの値を読み取り、その一部をSQL構文として解釈した時点で脆弱性が表面化します。
SQLインジェクションの例
ユーザーが制御できる情報を使ってデータベースクエリを生成する機能は、すべてSQLインジェクションの影響を受ける可能性があります。ログインページが説明例としてよく使われますが、検索機能、レポートツール、アカウントポータル、API、管理画面にも脆弱性が存在する可能性があります。
例1:安全でない検索機能
訪問者が選択したカテゴリに応じて商品を取得するアプリケーションを想定します。
query = "SELECT product_id, product_name
FROM products
WHERE category = '" + category + "'"
アプリケーションは、category に books や electronics などの通常値だけが含まれると想定しています。
この値がSQL文へ直接挿入されるため、想定外または悪意のある構文によってクエリの意味が変更される可能性があります。開発者は、代わりにパラメータ化クエリを使用する必要があります。
query = "SELECT product_id, product_name
FROM products
WHERE category = ?"
database.execute(query, [category])
パラメータ化したバージョンではクエリ構造が固定され、カテゴリ値はデータとして扱われます。OWASP SQL Injection Prevention Cheat Sheetでは、SQLインジェクション対策の最優先策として、プリペアドステートメントとパラメータ化クエリを推奨しています。
例2:安全でない動的レポート
レポートシステムでは、ユーザーがフィールド、テーブル名、並び順を選択できる場合があります。SQL文のこうした構造要素は、通常の値パラメータでは扱えないことがあります。
開発者は、ユーザーが送信したテーブル名やカラム名を直接クエリへ挿入せず、事前定義した許可リストへ選択値をマッピングする必要があります。
例:
allowed_sort_fields = {
"name": "customer_name",
"date": "created_at",
"status": "account_status"
}
sort_column = allowed_sort_fields.get(user_choice, "created_at")
アプリケーションはマッピングから信頼できるデータベース識別子を選択し、リクエストの元の値をSQL構文として扱いません。
OWASP SQL Injection Prevention Cheat Sheetでは、動的クエリ要素をバインドパラメータで表現できない場合、許可リストによる検証を推奨しています。
実際の事例:MOVEit Transfer
2023年、CL0Pランサムウェアグループは、Progress SoftwareのMOVEit Transfer製品に存在したCVE-2023-34362を悪用しました。
CISAとFBIの共同セキュリティ勧告によると、攻撃はMOVEit TransferのWebアプリケーションに存在するSQLインジェクション脆弱性から始まりました。この攻撃活動では、不正アクセス、Webシェルの展開、影響を受けたシステムからのデータ窃取が確認されています。
この事例からは、次の重要なセキュリティ上の教訓が得られます。
- インターネットに公開されたアプリケーションでは、継続的な脆弱性管理が必要です。
- SQLインジェクションが、より大規模な侵害の起点になる可能性があります。
- 組織には、迅速なパッチ適用とインシデント対応能力が求められます。
- 恒久的な修正が展開されるまで、監視と一時的なセキュリティ対策によって露出リスクを抑えられます。
- 単一のアプリケーション脆弱性による影響が、対象データベースの範囲を超えて広がることがあります。
SQLインジェクションの脆弱性と攻撃を検知する方法
検知には、安全な開発レビュー、許可を得たアプリケーションテスト、本番環境の監視を組み合わせる必要があります。どれか一つの方法だけで、すべてのSQLインジェクション脆弱性や攻撃試行を確実に特定することはできません。
アプリケーションのソースコードをレビューする
コードレビューにより、アプリケーションを展開する前に安全でないクエリパターンを特定できます。
レビュー担当者は、特に次の点を確認する必要があります。
- 文字列連結で生成されたSQL文
- 生のクエリ関数へ渡される、ユーザーが制御可能な値
- 動的に選択されるテーブル名、カラム名
- 動的SQLを生成するストアドプロシージャ
- バインドパラメータを使用していないデータベース呼び出し
- 安全でない生クエリを実行できるORM機能
- 過剰な権限を持つアプリケーション用データベースアカウント
O/Rマッピング(ORM)フレームワークを使用しても、SQLインジェクションを自動的に防げるわけではありません。生クエリ、安全でないクエリビルダー、ユーザーが制御できる値の不適切な処理によって、脆弱性が生じる可能性があります。
開発チームは、メインアプリケーション以外のデータベースアクセスポイントも確認する必要があります。バックグラウンドジョブ、レポートツール、管理ユーティリティ、データインポート処理なども対象です。
セキュリティテストを開発プロセスへ組み込む
アプリケーションセキュリティテストには、次のようなものがあります。
- 静的アプリケーションセキュリティテスト(SAST)
- 動的アプリケーションセキュリティテスト(DAST)
- インタラクティブアプリケーションセキュリティテスト(IAST)
- 人手によるセキュアコードレビュー
- セキュリティ回帰テスト
- 許可を得たペネトレーションテスト
テストでは、データベースとやり取りする可能性のある、すべての入力チャネルを対象にする必要があります。
- フォームフィールド
- URLパラメータ
- HTTPヘッダー
- Cookie
- APIリクエスト
- JSON、XML本文
- アップロードデータ
- 以前に保存された値
- バックグラウンドプロセス
OWASP Web Security Testing GuideのSQLインジェクションテストでは、SQLインジェクション箇所を特定し、攻撃者が取得し得るデータベースアクセス権限を評価するための体系的な手法が示されています。
テストは、テスト担当者が明示的な許可を得ているアプリケーションとシステムに対してのみ実施してください。本番環境でテストする場合は、サービス停止、データ損失、意図しないデータベース変更を避けるため、慎重な管理が必要です。
アプリケーションとセキュリティイベントを監視する
SQLインジェクション試行の兆候として、次のようなものが挙げられます。
- 形式が異常なリクエストの繰り返し
- URLやAPIパラメータ内の異常な入力
- データベース構文エラーの急増
- 同様のアプリケーションエラーを繰り返し発生させるリクエスト
- 異常な応答遅延
- データベースクエリ量の異常
- 極端に大きな結果セット
- 権限のないアクセス記録
- 機密データの予期しない変更
- 同一の送信元から繰り返し発生するWAF検知
単一の兆候には、正当な理由がある場合もあります。たとえば、データベースエラーがアプリケーションの不具合によって発生することや、異常なリクエスト量が承認済みの自動処理によるものであることも考えられます。
セキュリティチームは、アプリケーションログ、データベースログ、WAFイベント、認証システム、ネットワーク監視データを総合的に分析し、該当する活動が実際の攻撃かどうかを判断する必要があります。
セキュリティログとエラー情報を保護する
ログには、調査に必要な十分なコンテキストを含める一方、不要な機密情報は記録しないようにします。
パスワード、認証トークン、決済データ、セッション識別子はログから除外するか、適切に保護する必要があります。ログへのアクセスを制限し、不正な削除や改ざんから保護することも重要です。
一般公開されるアプリケーションレスポンスでは、詳細なデータベースエラー、クエリ本文、テーブル名、ソフトウェアバージョン、スタックトレース、内部ファイルパスを表示しないようにします。詳細な技術情報は、ユーザーに直接表示せず、保護された内部ログへ記録してください。
詳細なエラー情報を隠すことで攻撃者に与える情報は減らせますが、脆弱なクエリ自体を修正することはできません。
SQLインジェクションを防ぐ方法
効果的な防御は、安全なクエリ生成から始まります。さらに、入力検証、アクセス制御、テスト、実行時保護を組み合わせて強化します。
パラメータ化クエリを使用する
パラメータ化クエリとプリペアドステートメントは、SQLインジェクションを防ぐための主要な技術的対策です。
アプリケーションはプレースホルダーを使ってSQLコマンドを定義し、ユーザーが制御できる値を別途渡します。これにより、入力値がクエリ構造を変更することを防げます。
OWASP SQL Injection Prevention Cheat Sheetでは、第一の対策としてパラメータ化クエリを推奨しています。
SQL文字列の連結を避ける
アプリケーションは、クエリ文字列と信頼できない値を直接連結してSQLコマンドを生成してはいけません。
信頼できないデータは、フォーム、URL、ヘッダー、Cookie、API、アップロードファイル、サードパーティ連携、メッセージキュー、以前にデータベースへ保存された値など、さまざまな場所から入ってきます。
パラメータ化に対応したデータベースAPIを使用することで、この種の脆弱性を根本から防げます。
ストアドプロシージャを安全に使用する
ストアドプロシージャでパラメータを使用し、動的SQLを避ければ、SQLインジェクションのリスクを軽減できます。
ただし、ストアドプロシージャ内で入力値を連結したり、動的に生成した文を実行したりする場合は、脆弱性が残る可能性があります。ストアドプロシージャでも、SQLコマンドと信頼できないデータを分離する必要があります。
許可リストによる検証を行う
入力検証では、送信された値が想定される形式、範囲、許可された選択肢に合致しているかを確認します。
たとえば、識別子を数値のみに限定する、ステータス項目を事前定義した値に制限する、日付形式を検証する、並び順の選択肢を信頼できるカラム名へマッピングする、といった方法があります。
入力検証はパラメータ化クエリと併用する必要があり、その代替にはなりません。拒否リストだけに依存する方法は、SQL構文にさまざまな表現方法があるため、十分な対策にはなりません。
最小権限の原則を適用する
アプリケーションのデータベースアカウントには、通常の機能を実行するために必要な権限だけを付与します。
たとえば、レポートアプリケーションに必要なのは読み取り権限だけであり、変更権限は不要な場合があります。顧客向けアプリケーションが、データベース管理者アカウントで接続することも避けるべきです。
最小権限によって脆弱性そのものがなくなるわけではありませんが、攻撃が成功した場合の被害を限定できます。
エラー情報を制御し、継続的にテストする
アプリケーションはユーザーに一般的なエラーメッセージを表示し、技術的な詳細はアクセス制限された内部ログへ記録する必要があります。
セキュリティテストは、設計、開発、展開、保守の全工程で継続して実施します。重要な取り組みには、コードレビュー、自動セキュリティテスト、ペネトレーションテスト、回帰テスト、依存関係の更新、データベースアクセス権限の見直しがあります。
組織はベンダーのセキュリティ勧告を継続的に確認し、脆弱性のあるアプリケーション、フレームワーク、プラグイン、サードパーティソフトウェアを速やかに更新する必要があります。
WAFで多層防御を実現する
Webアプリケーションファイアウォールは、HTTPおよびHTTPSリクエストを検査し、既知のさまざまな攻撃パターンを遮断し、疑わしい活動を可視化できます。また、恒久的な修正が完了するまで、仮想パッチによってリスクを抑えることも可能です。
WAFは脆弱なコードを修正できず、すべてのSQLインジェクション手法を確実に遮断できるわけでもありません。パラメータ化クエリの採用と脆弱性の修正は、引き続き不可欠です。
OWASPのWAFを回避するSQLインジェクション手法に関する資料では、実行時保護と安全なアプリケーション開発を組み合わせる重要性が説明されています。
CDNetworksによるSQLインジェクション対策
SQLインジェクションを防ぐうえで最も効果的なのは、脆弱なアプリケーションコードを修正することです。CDNetworksは脆弱性テストを通じてこの取り組みを支援し、アプリケーション内のセキュリティ上の弱点を特定します。これにより、開発チームとセキュリティチームは修正の優先順位を判断できます。
CDNetworks Web Application Firewallは、HTTPおよびHTTPSリクエストがオリジンアプリケーションへ到達する前に検査し、保護層を追加します。世界3,000以上のPoPを基盤に、1,000以上の組み込みセキュリティルールと、AIおよび機械学習による分析を組み合わせ、既知のSQLインジェクションパターンと継続的に変化する攻撃パターンを検知します。
ルールの自動更新、カスタムセキュリティポリシー、仮想パッチにより、恒久的な修正の開発・展開中も露出リスクを軽減できます。これらの対策は、多層防御の一部として、パラメータ化クエリ、入力検証、データベースへの最小権限アクセスと連携します。
CDNetworksのセキュリティサービスには、脆弱性診断とペネトレーションテストも含まれます。
CDNetworks WAFを今すぐ無料でお試しいただくか、Web Application Firewallの製品資料をダウンロードしてください。
よくある質問
SQLインジェクションとはどういう意味ですか?
SQLインジェクションとは、信頼できない入力によってデータベースクエリが変更されるセキュリティ脆弱性です。不正なデータアクセス、変更、削除、認証回避、データベース管理操作につながる可能性があります。
SQLインジェクションはサイバー攻撃ですか?
SQLインジェクションは、アプリケーション層を狙うサイバー攻撃です。攻撃者は安全でないデータベースクエリを悪用し、データへのアクセス、変更、削除、認証回避、アプリケーションが想定する権限を超えた操作を試みます。
SQLとSQLインジェクションの違いは何ですか?
SQLは、リレーショナルデータベースを操作するための言語です。SQLインジェクションは、信頼できない入力によってデータベースクエリ本来の構造や動作が変更される脆弱性です。
SQLインジェクション攻撃にはどのような例がありますか?
検索フォームの入力値をSQLクエリへ直接挿入すると、脆弱性が生じる可能性があります。パラメータ化クエリを使用すれば、入力値が実行可能なSQL構文として解釈されることを防げます。
SQLインジェクションの影響を受けるデータベースはどれですか?
アプリケーションが安全でない方法でクエリを生成している場合、リレーショナルSQLシステムを使用するデータベースは影響を受ける可能性があります。具体的な構文や影響は、データベースプラットフォーム、プログラミング言語、ドライバー、アプリケーションフレームワークによって異なります。
