はじめに
SQL Injection(SQLi)は、Web セキュリティ界の“古参だけど現役バリバリの強敵”。
脆弱性診断でも Web アプリケーション開発でも、必ず出てくる ― つまり 「避けて通れない宿題」 です。
本記事では、
・Secure Coders(開発者)
・Pentesters(攻撃者/診断者)
の両側から「どう守り、どう攻めるか」を分かりやすく整理します。
攻防両面を知ることで、対策はより深まり、攻撃はより賢くなる。
まさに“一粒で二度美味しい”記事です。
Secure Coders(守る側)がやるべきこと
1. パラメータ化クエリ(Prepared Statements)
SQLi 対策の 絶対王者。
ユーザー入力と SQL 構文を分離することで、インジェクションの余地を根こそぎ削る。
例(PHP PDO):
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
$stmt->execute(['username' => $username]);
これで ' OR 1=1 -- みたいな“お約束”攻撃は完全に無効化。
2. 入力バリデーション & サニタイズ
「想定外のデータは入口で止める」。
これはアプリケーションの“空港保安検査”みたいなものです。
例えば:
- 型チェック(int以外は拒否)
- 長さ制限(100文字以内など)
- 形式チェック(メール、URL、電話番号)
PHPでの例:
$username = filter_var($_POST['username'], FILTER_SANITIZE_STRING);
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
“なんでも通す API”は脆弱性の温床。
あなたのサービスを“自由研究の実験台”にしないためにも必須。
3. 最小権限の原則(Least Privilege)
アプリの DB ユーザーに root や SUPER 権限を付けるのは、
包丁を持った子どもに家中を任せるレベルで危ない。
アプリで必要なのは通常:
- SELECT
- INSERT
- UPDATE
- DELETE
これだけで充分。
インジェクションが起きても、権限が低ければ“大事故にならない”。
4. ストアドプロシージャ(Stored Procedures)
SQL ロジックを DB 内部に閉じ込めることで、
- 入力の一元管理
- 動的 SQL を減らす
など、構造的に安全性が上がります。
ただし注意:
“動的 SQL を内部で組み立てるストアド”は逆に危険
(よくある危険パターン)。
5. 定期的なコードレビュー & セキュリティ監査
自分のコードは可愛いので欠点を見落としがち。
第三者レビュー・自動スキャンは必須。
- SAST(静的解析)
- DAST(動的解析)
- 手動レビュー(ここ大事)
攻撃は進化します。防御もアップデートが必要。
Pentesters(攻める側)が押さえるべき技術
ここからは“攻撃者の目”。
防御を理解しつつ、どう突破するのか。
1. DBMS 特有の機能を攻める
SQLi は「DBMS によって攻撃ベクトルが変わる」。
例:
| DBMS | 面白い攻撃ポイント |
|---|---|
| MySQL | LOAD_FILE(), INTO OUTFILE |
| MSSQL | xp_cmdshell、OPENROWSET |
| PostgreSQL | COPY … TO PROGRAM |
| Oracle | UTL_HTTP、DBMS_LDAP |
DB-specific な機能を知る=武器が増える。
2. エラーメッセージを利用した情報収集
エラーが verbose ならそこは宝の山。
例(MSSQL):
1' AND 1=CONVERT(int, (SELECT @@version)) --
エラー文に DB バージョンが漏れる。
まさに“しゃべるバグ”。
3. WAF / フィルタ回避テクニック
WAF を騙すテクは SQLi の醍醐味。
- 大文字・小文字混在 →
SeLeCt - inline コメント →
UN/**/ION - 文字コード変換 →
%09,%0A, hex - CHAR() 連結 →
CONCAT(CHAR(83),...) - no-space SQLi →
SELECT/**/1
「WAFを突破できるかどうか」=ペンテスターの腕の見せ所。
4. DB 指紋取得(Fingerprinting)
DBMS が分かれば“攻撃メニュー”も確定。
例:
- MySQL / MSSQL →
SELECT @@version - PostgreSQL →
SELECT version() - Oracle →
SELECT * FROM v$version
特定できれば Exploit 路線が一気に明確に。
5. SQLi からの横展開(Pivoting)
SQLi は終点じゃなく起点。
- DB 内の認証情報 → 他システム侵害へ
- SMB/HTTP/DNS 経由 → OOB 攻撃
- FILE READ → Config → 次の侵害
SQLi は“単独のバグ”ではなく
ネットワーク侵入口そのもの になり得るのです。
まとめ:攻防両面を知れば対策と検査の質が跳ね上がる
SQL Injection は古くても色褪せない脅威。
しかし、正しい防御と深い理解があれば、リスクは大幅に減らせます。