対象試験と出題頻度

2024年、KADOKAWAグループへのサイバー攻撃で大量の個人情報が流出し、大きなニュースになりました。

Webアプリケーションの脆弱性を突く攻撃の代表格が、このSQLインジェクションです。

IPA試験では午前・午後を問わず繰り返し出題されており、サイバー攻撃の中でも最優先で押さえるべきテーマです。

対象試験と頻出度を確認する
対象試験:
ITパスポート
情報セキュリティマネジメント
基本情報技術者
応用情報技術者
出題頻度:
★★★★★
ランクS(超重要)絶対に覚える必要あり

用語の定義

セキュリティの勉強を始めると、「SQLインジェクションとクロスサイトスクリプティングって何が違うの?」「対策のプレースホルダって何?」と混乱しがちです。

SQLインジェクション(SQL Injection)とは、一言で言うと

 「Webアプリの入力欄に不正なSQL文を紛れ込ませ、データベースを不正に操作する攻撃

です。

イメージとしては、注文用紙の余白に店員への指示書を書き足す行為です。

レストランの注文用紙に「カレーライス1つ」と書くべきところに、「カレーライス1つ。ついでに金庫の中身を全部テーブルに出せ」と書き加えるようなもの。本来は注文(データ)しか受け付けない欄に、店員(データベース)への命令を混入させるのがこの攻撃の本質です。

📊 SQLインジェクションの基本情報

項目 内容
英語名 SQL Injection
攻撃の分類 脆弱性悪用型(Webアプリの入力処理の欠陥を突く)
狙う対象 サーバ側のデータベース
主な被害 個人情報の漏えい、データ改ざん・削除、認証回避による不正ログイン
根本的対策 プレースホルダ(バインド機構)によるSQL文の組み立て
公的参照元 IPA「安全なウェブサイトの作り方」1.1節 / CWE-89 / OWASP Top 10(Injection)

解説

Webアプリケーションの多くは、利用者が入力した値をもとにSQL文(データベースへの命令文)を組み立て、データベースに問い合わせています。

ログインフォームに入力されたIDをもとに「このIDの会員情報を返せ」という命令を自動生成する、といった処理です。

この「SQL文の組み立て方」に不備があると、攻撃者が入力値に命令文の断片を紛れ込ませることで、開発者が意図しないクエリが実行されてしまいます。

攻撃が成功する流れ(3ステップ)

具体的に、ログインフォームを例にして攻撃の流れを追います。

攻撃の流れ:ログインフォームの場合

Step 1:正常な処理を確認する

アプリ内部では、利用者の入力値をそのままSQL文に埋め込んでいる。

SELECT * FROM users WHERE uid = ‘taroAND pw = ‘pass123

▲ 利用者が「taro」「pass123」と入力 → 正常にログイン判定される

Step 2:攻撃者が不正な文字列を入力する

パスワード欄に ' OR '1'='1 と入力する。

SELECT * FROM users WHERE uid = ‘taroAND pw = ‘‘ OR ‘1’=’1

'1'='1'は常にtrue → WHERE句全体がtrueになる

Step 3:不正ログインが成立する

パスワードを知らなくても条件式が常にtrueになるため、認証を突破される。会員テーブルの全レコードが返却され、個人情報が流出する。

この攻撃が成立する根本原因は、「利用者の入力値」と「SQL命令文」を区別せずに文字列連結している点にあります。

入力値がそのままSQL構文の一部として解釈されるため、攻撃者は構文を壊して自由に命令を追加できるわけです。

なぜプレースホルダで防げるのか

根本的な対策は、SQL文の中で入力値が入る場所を「?」や「$1」などの記号(プレースホルダ)で確保しておき、後からデータベースエンジン側で値を安全に割り当てる方法です。

IPAの「安全なウェブサイトの作り方」でも第一に推奨されています。

— プレースホルダを使ったSQL文の雛形

SELECT * FROM users WHERE uid = ? AND pw = ?

— PHPでの実装例

$sql = ‘SELECT * FROM users WHERE uid = ? AND pw = ?’;
$stmt = $pdo->prepare($sql);
$stmt->execute([$uid, $pw]);  // ?に値をバインド

▲ ?の位置には「値」としてのみ割り当てられるため、SQL構文を壊すことが不可能になる

プレースホルダを使うと、入力値は常に「データ」として扱われ、SQL命令の一部として解釈されることがありません。

仮に ' OR '1'='1 と入力しても、その文字列がそのまま値として処理されるだけで、構文は変化しません。

図解:攻撃と対策の構造比較

❌ 脆弱な実装(文字列連結)

利用者の入力値
' OR '1'='1
⬇️ そのまま連結
SQL文の一部として
解釈される
⬇️
認証回避・情報漏えい

✅ 安全な実装(プレースホルダ)

利用者の入力値
' OR '1'='1
⬇️ 値としてバインド
ただの文字列データ
として処理される
⬇️
SQL構文は変化しない → 安全

XSSとの決定的な違い

同じ「入力欄を悪用する攻撃」としてクロスサイトスクリプティング(XSS)と混同されやすいですが、狙う場所が正反対です。

SQLインジェクションはサーバ側のデータベースを操作するのに対し、XSSは利用者のブラウザ上でスクリプトを実行させます。「どこを攻撃するか」を基準にすれば、両者を取り違えることはありません。

覚えるのはこの3点だけ

・入力欄に不正なSQL文を混入させ、サーバ側のDBを不正操作する攻撃
・根本対策はプレースホルダ(バインド機構)でSQL文を組み立てること
・XSSはブラウザを狙い、SQLインジェクションはDBを狙う――標的が逆


試験ではこう出る!

SQLインジェクションは、全試験区分の午前問題で繰り返し出題されています。

AP午後でも令和6年秋に大問1で本格的に扱われました。

出題パターンは主に2つです。

📊 過去問での出題実績

試験回 出題内容 問われたポイント
IP R4
問95
不正に入手した認証情報を流用する攻撃手法の判別。 ・正解は「パスワードリスト攻撃」
・選択肢にSQLインジェクションが登場し、違いを区別できるかを問う
SG R5
科目A 問7
Webアプリのセキュリティ脅威と対策の正しい組み合わせを選ぶ。 ・「SQLインジェクション + プレースホルダ」が正解
・OSコマンドインジェクションやセッションハイジャックの対策が入れ替わったひっかけ
FE R6
科目A 問10
(免除 問33)
SQLインジェクション対策として有効なものを選ぶ。 ・正解は「プレースホルダを使って命令文を組み立てる」
・他の選択肢はXSS対策やディレクトリトラバーサル対策
AP R6秋
午後 問1
ECサイトのペネトレーションテストで発見された脆弱性を題材にした大問。 ・プレースホルダの仕組みを記述式で回答
・レインボーテーブル攻撃・ソルト・ペッパーとの組み合わせで多層防御を問う

📝 出題パターンの整理

パターン1:「攻撃名 × 対策」の正しい組み合わせを選べ
選択肢には「SQLインジェクション → プレースホルダ」「XSS → エスケープ処理」「ディレクトリトラバーサル → ファイル名の直接指定禁止」「OSコマンドインジェクション → シェル起動の禁止」が並ぶ。対策がシャッフルされるため、攻撃と対策の1対1対応を正確に覚えているかが問われる。

パターン2:「この攻撃は何か」を被害内容から判別させる
「入力フォームから不正な命令を送り込み、データベースの内容を取得した」→ SQLインジェクション、という判別。フィッシングやDoS攻撃の説明と混ぜて出される。

午前対策は「プレースホルダ=SQLインジェクション対策の切り札」を覚えれば得点ラインに届きます。AP午後まで視野に入れるなら、静的プレースホルダと動的プレースホルダの違い、WAFとの多層防御まで押さえておくと安心です。


受験生が間違えやすい「対策のすり替え」パターン

FE R6 問10やSG R5 問7に共通するのが、「他の攻撃の対策をSQLインジェクションの対策として提示する」ひっかけです。ここだけは確実に押さえてください。

選択肢の記述 本当の対策対象 見分けポイント
プレースホルダを使って命令文を組み立てる SQLインジェクション ✅ SQL文の構造を固定する
URLをhttp://やhttps://で始まるものだけ許可する XSS javascript:スキームの排除
外部パラメータでファイル名を直接指定しない ディレクトリトラバーサル ファイルパスの制御
Webアプリからシェルを起動できないようにする OSコマンドインジェクション OS命令の実行経路を遮断

4つの攻撃と4つの対策がシャッフルされて出題されるのが定番です。上記の対応関係をセットで記憶しておけば、選択肢を即座に判別できます。


【確認テスト】理解度チェック


Q. Webアプリケーションにおけるセキュリティ上の脅威と対策の組み合わせとして、最も適切なものはどれか。

  • A. SQLインジェクションを防ぐために、Webアプリケーションからシェルを起動できないようにする。
  • B. SQLインジェクションを防ぐために、Webアプリケーション内でデータベースへの問い合わせを作成する際にプレースホルダを使用する。
  • C. SQLインジェクションを防ぐために、外部からのパラメータでWebサーバ内のファイル名を直接指定できないようにする。

正解と解説を見る

正解:B

解説:
プレースホルダ(バインド機構)は、SQL文の雛形の中で入力値が入る箇所を専用記号で確保し、データベースエンジン側で値を安全に割り当てる仕組みです。入力値がSQL命令として解釈されなくなるため、SQLインジェクションの根本的な対策になります。

選択肢Aの「シェルを起動できないようにする」はOSコマンドインジェクションへの対策です。OSコマンドインジェクションは、入力値を通じてOSのコマンドを不正に実行させる攻撃であり、シェルの起動経路を断つことで防ぎます。選択肢Cの「ファイル名を直接指定できないようにする」はディレクトリトラバーサルへの対策です。「../」などで本来アクセスできないファイルを読み取る攻撃に対し、パスの外部指定を禁止することで防ぎます。


よくある質問(FAQ)

Q. エスケープ処理とプレースホルダは何が違うのですか?

エスケープ処理は、入力値の中のシングルクォートなどSQL構文上特別な意味を持つ文字を無害な形に変換する手法です。一方プレースホルダは、SQL文の構造そのものを先に確定させ、入力値は「データ」として後から割り当てます。エスケープ処理はデータベースの種類や設定に依存する実装ミスのリスクがあるのに対し、静的プレースホルダ(Prepared Statement)は原理的にSQL構文の変化が起きないため、IPAも「まずプレースホルダで実装すること」を第一の対策として推奨しています。

Q. WAF(Web Application Firewall)を導入すればSQLインジェクションは完全に防げますか?

WAFだけでは完全には防げません。WAFは不正なリクエストパターンを検知・遮断する「保険的対策」であり、未知の攻撃パターンや巧妙に難読化されたリクエストをすり抜ける可能性があります。AP R6秋 午後 問1でもWAFは導入済みの状態でペネトレーションテストが実施され、「WAFだけに頼らず本システム自体でも対策する=多層防御」の考え方が問われました。WAFとプレースホルダの併用が実務のセオリーです。

Q. SQLインジェクションはログインフォーム以外でも起きるのですか?

起きます。検索フォーム、問い合わせフォーム、URL内のパラメータ、Cookieの値、HTTPヘッダなど、アプリケーションが受け取るあらゆる入力がSQL文の組み立てに使われている箇所すべてが攻撃対象になり得ます。IPAの「安全なウェブサイトの作り方」でも、外部からの入力の影響を受ける値だけでなく「SQL文を構成する全てのリテラル生成」に対してプレースホルダやエスケープ処理を適用すべきとしています。

Q. ストアドプロシージャを使えばSQLインジェクションは防げますか?

ストアドプロシージャを使うと、アプリケーション側にSQL文を直接記述しなくて済むため、リスクの低減にはつながります。ただし、ストアドプロシージャ内部で文字列連結によりSQL文を動的に組み立てている場合は、同じ脆弱性が発生します。ストアドプロシージャ内でもプレースホルダ相当の仕組みを使うことが前提です。


関連用語ネットワーク

【前提知識】 SQL(DROP文) / データベース / Webアプリケーション

【関連する攻撃】 XSS / OSコマンドインジェクション / ディレクトリトラバーサル

【防御側の用語】 WAF / プレースホルダ(バインド機構) / エスケープ処理 / 多層防御