エラーベース - エラーベース SQL インジェクション
データベースのエラーメッセージを意図的に発生させ、エラー内容からデータベース構造やデータを取得する手法。
概念図
エラーベース攻撃の基本原理
エラーベース SQL インジェクションは、DB が返すエラーメッセージに「評価したクエリ結果や値の一部」を含める機能を悪用し、1 回の HTTP レスポンスで任意のデータを取り出す手法である。
UNION ベースのように結果表示用のカラムを必要とせず、時間ベースのブラインド攻撃のように数秒待つ必要もない。
| 比較項目 | UNION ベース | ブラインド | エラーベース |
|---|---|---|---|
| 必要な表示経路 | 正常結果の表示 | 真偽 / 応答時間 | エラーメッセージ本文 |
| 1 リクエストで得られる情報 | 多い(複数行可) | 1 ビット | 1 値(~数十文字) |
| 抽出速度 | 高速 | 低速 | 高速 |
| 典型的な失敗条件 | カラム数調整不可 | 応答差分なし | 詳細エラーを画面に出さない |
エラーベース攻撃が成立する典型的な条件は次のとおりである。
- アプリケーションが DB の例外メッセージをそのままレスポンスに出力している(スタックトレース、500 ページ、JSON エラーフィールド等)
- あるいは DB エラー文字列をログ画面・管理画面経由で閲覧できる
- DB 側で詳細なエラーメッセージ生成が有効になっている(多くの RDBMS のデフォルト)
本番環境で詳細なエラーメッセージを出さない運用(カスタムエラーページ・一律 500 表示)が徹底されていれば、エラーベース攻撃の成立確率は大きく下がる。
DB 別の代表的ペイロード
エラーベース攻撃で使われる関数は DB ごとに異なる。
以下は代表的なパターンの一覧である。
| DB | 活用関数・機構 | 原理 |
|---|---|---|
| MySQL | EXTRACTVALUE, UPDATEXML |
XPath 式にデータを埋め込むと XPath 構文エラーでその値がエラーメッセージに現れる |
| MySQL | GROUP BY + FLOOR(RAND(0)*2) |
重複キーエラー Duplicate entry ... に評価値を含めさせる古典技 |
| PostgreSQL | CAST 型変換エラー |
文字列を integer にキャストすると invalid input syntax for integer: "..." に値が出る |
| PostgreSQL | to_regclass / json_* 系 |
不正入力時のエラーに識別子が露出する |
| MSSQL | CAST / CONVERT 型変換 |
文字列 → int 変換で Conversion failed when converting the varchar value '...' |
| Oracle | CTXSYS.DRITHSX.SN |
XPath/テキストインデックス系の関数でエラー文にデータが出る |
| Oracle | DBMS_XDB_VERSION 系 |
一部バージョンでエラー文字列から情報抽出可能 |
実際のペイロード例を示す。
-- MySQL: UPDATEXML で現在 DB 名を漏洩させる
1 AND UPDATEXML(1, CONCAT(0x7e, (SELECT DATABASE()), 0x7e), 1)--
-- MySQL: EXTRACTVALUE で管理者パスワードの一部を抽出
1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT SUBSTRING(password,1,20) FROM users WHERE id=1), 0x7e))--
-- PostgreSQL: CAST エラーを利用して version() を漏洩
1 AND 1=CAST((SELECT version()) AS INTEGER)--
-- MSSQL: CONVERT 型変換エラーを利用
1 AND 1=CONVERT(int, (SELECT TOP 1 name FROM sys.databases))--
MySQL の UPDATEXML / EXTRACTVALUE は「不正な XPath 式のテキスト」をエラーに含める仕様のため、~ などの区切り文字で挟んだ SELECT 結果がそのままレスポンスに返ってくる。
PostgreSQL / MSSQL の CAST 系は、文字列を整数に変換しようとした際のエラーメッセージに変換元の文字列がそのまま表示される性質を悪用する。
本番環境で効く軽減策
エラーベース攻撃はアプリケーションと DB の両面から多層的に塞ぐことができる。
特に「エラー情報を外に出さない」ことは、他の SQLi 種別と比べて極めて効果的な追加ディフェンスである。
| 層 | 対策 | 概要 |
|---|---|---|
| アプリ | カスタムエラーページ | 例外を捕捉し、ユーザー向けには汎用メッセージのみ返す。スタックトレース・SQL 文・DB エラー文を画面に出さない |
| アプリ | 構造化ログへの分離 | 詳細なエラーはサーバ側ログにのみ記録し、HTTP レスポンスには含めない |
| アプリ | JSON API のエラーフィールド整備 | error: "internal error" 固定とし、例外メッセージを流さない |
| DB | アプリ用ユーザーの権限最小化 | EXTRACTVALUE 等の関数利用自体は止められないが、information_schema / sys 系の参照権限を削ると抽出できる情報が狭まる |
| DB | 詳細エラー設定の見直し | MSSQL の xp_cmdshell 無効化など、悪用されやすい機能を無効にする |
| 境界 | WAF シグネチャ | EXTRACTVALUE(, UPDATEXML(, CONVERT(int, 等の特徴的キーワードを検知 |
| 境界 | アノマリ検知 | 5xx / 500 が特定 IP から短時間に大量発生するパターンを監視 |
エラーメッセージ非表示の対策は、エラーベース SQLi だけでなく、パストラバーサルや権限不足エラーからの情報漏洩など広範な脆弱性に効く。
開発環境では詳細エラーを有効にし、本番環境ではビルド時フラグや環境変数で必ず無効化する運用を徹底することが望ましい。
