「SQLインジェクション攻撃を防ぐ方法はどれか」という設問は、情報処理安全確保支援士(SC)試験の午前IIで繰り返し問われてきた定番テーマであり、午後の記述問題でも高頻度で登場します。私はCIO時代、WAFが高価で運用ハードルも高く導入を見送り、Webサーバー側のアクセス制御設定(ハードニング)で泥臭く守っていました。当時から「入力値をどう扱うか」というアプリケーション側の設計こそが本丸だと痛感しています。
本記事では、午前IIの過去問「SQLインジェクション攻撃を防ぐ方法はどれか」の解答と選択肢の見分け方から始め、発生メカニズム、根本的対策、午後の記述解答の組み立て方までを一気通貫で解説します。キーワードの暗記から脱却し、どのパターンで問われても論理的に正解を導ける実力を身につけましょう。
【午前II過去問】「SQLインジェクション攻撃を防ぐ方法はどれか」の答えと解説
まずは検索でたどり着く方が最も多い、午前IIの4択問題から片付けます。この設問は情報セキュリティスペシャリスト試験(SCの前身)平成22年秋期 午前II 問8として出題され、その後もSC試験で類似の問い方が繰り返されています。答えを先に示し、なぜそれが正解でほかが誤りなのかを、攻撃対策の対応関係から解説します。
正解はイ:特別な意味をもつ文字を解釈させない
設問:「SQLインジェクション攻撃を防ぐ方法はどれか。」
- ア 入力から、上位ディレクトリを指定する文字列(
../)を取り除く。 - イ 入力中の文字がデータベースへの問合せや操作において特別な意味をもつ文字として解釈されないようにする。
- ウ 入力にHTMLタグが含まれていたら、解釈、実行できないほかの文字列に置き換える。
- エ 入力の全体の長さが制限を超えていたときは受け付けない。
正解は「イ」です。SQLインジェクションは、利用者の入力値がSQLの構文として解釈されてしまうことで発生します。したがって、入力中の文字がデータベースへの問合せにおいて特別な意味をもつ文字(シングルクォーテーション ' など)として解釈されないようにする対策が、直接の防止策になります。具体的には、後述するプレースホルダ(バインド機構)による構文とデータの分離や、エスケープ処理がこれに該当します。
選択肢ア・ウ・エがなぜ誤りか(別の攻撃への対策と区別する)

この問題の狙いは、SQLインジェクションと「別の攻撃への対策」を混同させることにあります。それぞれが何の対策なのかを整理すると、迷わず消去できます。
- ア(
../の除去): ディレクトリトラバーサル(パストラバーサル)攻撃への対策です。ファイルパスに../を挿入して想定外のファイルを読み出す攻撃を防ぐもので、SQL文の組み立てとは無関係です。 - ウ(HTMLタグの置換): クロスサイトスクリプティング(XSS)への対策です。出力時にHTMLタグを無害な文字列へエスケープし、ブラウザ上でのスクリプト実行を防ぎます。処理する層(出力=ブラウザ側)がSQLインジェクション(入力=データベース側)とは異なります。
- エ(入力長の制限): バッファオーバーフローなど、長すぎる入力に起因する攻撃への対策です。長さを制限しても、短い攻撃文字列(例:
' OR ''='は9文字)で成立するSQLインジェクションは防げません。
学び始めの人がやりがちなのが、「入力値を検証する対策はどれも同じ」とまとめて覚えてしまうことです。SQLインジェクション(DB)、XSS(ブラウザ)、ディレクトリトラバーサル(ファイルシステム)、バッファオーバーフロー(メモリ領域)は、それぞれ「注入先」が異なります。注入先で答えを選ぶ癖をつけると、午前IIの類似問題を安定して得点できます。
関連する午前問題:プレースホルダと最小権限の組合せ
近年のSC試験(令和元年秋期 午前II 問17、令和5年春期 午前II 問17など)では、「Webアプリケーションプログラムの実装における対策と、実装以外の対策の組合せ」を問う形式が出ています。正解の組合せは、実装側=プレースホルダ(バインド機構)、実装以外=データベースアカウントの最小権限です。単一の対策だけでなく「根本的対策+多層防御」をセットで押さえておくと、この出題パターンにも対応できます。プレースホルダそのものの内部動作は次章で詳述します。
テンプレート集
+おまけ:毎日1通の無料メール講座つき。登録した日が「1日目」、図解と論理で16週間かけて基礎も固まります。
SQLインジェクションのメカニズムを完全解剖する
記述問題に対応するためには、まず「なぜこの脆弱性が発生するのか」を自分の言葉で正確に説明できるレベルまで落とし込む必要があります。
脆弱性の根本原因:データと構文の混同
Webアプリケーションは、利用者の入力値(検索キーワードやログインIDなど)を受け取り、データベースを操作するSQL文を動的に組み立てます。この際、入力値にSQLの構文として意味を持つ特殊文字(シングルクォーテーション ' やセミコロン ; など)が含まれていると、開発者が意図したSQL構造が破壊され、攻撃者が注入した不正なSQL文が実行されてしまいます。これがSQLインジェクションです。
例えば、ユーザーIDを検索する以下のSQL文を文字列連結で生成しているとします。
SELECT * FROM users WHERE user_id = '入力値' AND password = 'パスワードの入力値'
入力値として admin' -- が与えられると、生成されるSQL文は次のようになります。
SELECT * FROM users WHERE user_id = 'admin' --' AND password = 'パスワードの入力値'
SQLにおいて -- はコメントアウトを意味するため、以降の条件が無視されます。結果として、パスワード検証をスキップして admin ユーザーとしてログインできてしまいます。「単なる文字列データ」として扱われるべき入力値が、「SQLの構文(コード)」として解釈されてしまうことが悲劇の根源です。

攻撃者が駆使する多様な攻撃手法
攻撃者はシステムからのわずかな応答を利用して、巧みにデータベースから情報を引き出します。試験で問われやすい代表的な手法は以下の3つです。
- UNIONベースのインジェクション: 元のSQL文に
UNION SELECT句を追加し、攻撃者が指定した別テーブルのデータを検索結果に結合させて画面に表示させる手法です。本来アクセスできない個人情報や認証情報を一括で抜き取られます。 - エラーベースのインジェクション: 不正なSQL文を意図的に実行させ、データベースが返すエラーメッセージにバージョン情報やテーブル名などを含ませる手法です。詳細なエラーメッセージは攻撃者にとって格好の手がかりとなります。
- ブラインドSQLインジェクション: 画面に直接結果が表示されない場合でも、「応答時間の違い(Time-based)」や「画面のわずかな変化(Boolean-based)」を利用して一文字ずつデータを推測する高度な手法です。
企業に与えるビジネスインパクト
SQLインジェクションの被害は単なるシステム障害にとどまりません。顧客のクレジットカード情報や個人情報の大量漏えいは、企業の社会的信用の失墜、損害賠償による巨額の経済的損失、事業継続の危機に直結します。データの不正な書き換えが発生すればシステム全体の信頼性が崩壊し、さらにDBサーバーを経由したOSコマンド実行でランサムウェア感染の起点とされるケースもあります。その影響は計り知れません。
根本的対策と多層防御による堅牢なシステム構築
脆弱性の原因を理解した後は「どう防ぐか」を整理します。試験の記述問題では、「根本的対策」 と 「保険的対策(多層防御)」 を明確に区別して論述できることが求められます。
根本的対策の王道:プレースホルダ(バインド変数)の利用
SQLインジェクションを防ぐ最も確実な根本的対策が、プレースホルダ(バインド変数) を利用したSQL文の組み立てです。
プレースホルダとは、SQL文の中で後から値を当てはめる場所を ? などの記号で確保しておく仕組みです。静的プレースホルダを利用する場合、データベースエンジンはまず「値が空の状態のSQL構文」を解析(コンパイル)します。構文解析が完全に終了した後、初めて入力値がプレースホルダに割り当て(バインド)されます。
この順序が極めて重要です。すでに構文解析が終わっているため、後からバインドされる入力値の中にどのような悪意あるSQL構文(OR 1=1 など)が含まれていても、データベースはそれらを「単なる文字列データ」としか扱いません。SQLの構文が後から改変される余地が物理的に存在しないため、SQLインジェクションを根絶できるのです。プレースホルダの内部動作を実装コード付きでさらに深掘りした解説は、SQLインジェクション対策の本命「プレースホルダ」を仕組みから理解するで扱っています。

やむを得ない場合のエスケープ処理とその限界
レガシーシステムの改修などでプレースホルダを利用できず、文字列連結でSQL文を組み立てざるを得ない場合の次善策が「適切なエスケープ処理」です。
エスケープ処理とは、入力値に含まれる特殊文字(メタ文字)の前にエスケープ文字を付与したり、規定の表現へ置き換えたりして、その特別な意味を打ち消して単なる文字として扱わせる処理です。例えばシングルクォーテーション ' を ''(2つ重ねる)に変換します。
ただし、データベース製品や文字コードの設定によってエスケープ仕様が微妙に異なる場合があり、漏れなく完璧に実装することは難しく、ミス(脆弱性)が混入しやすい欠点があります。基本的にはプレースホルダの利用を第一選択とすべきです。
被害を最小化する多層防御アプローチ
根本的対策を講じた上でも、予期せぬ実装漏れや新たな攻撃手法に備えるため、複数の防御層を設ける「多層防御(Defense in Depth)」の考え方が不可欠です。
- WAF(Web Application Firewall)の導入: Webサーバーの手前でHTTP通信を監視し、SQLインジェクション特有の攻撃パターン(シグネチャ)を含むリクエストを検知・遮断します。
- データベースアカウントの権限最小化: アプリケーションがDBに接続する際のアカウントに管理者権限を与えないことです。テーブルの参照(SELECT)のみが必要な機能であれば、更新(UPDATE)や削除(DELETE)権限を持たない専用アカウントを使用することで、万一インジェクションが成功しても被害範囲を限定できます。
- エラーメッセージの隠蔽: データベースが出力する詳細なエラーメッセージを利用者のブラウザにそのまま表示させないよう制御します。これにより、攻撃者にシステムの内部構造を推測させるヒントを与えません。
午後試験の記述問題で狙われる頻出パターンと解答の型
午後試験の記述問題では、問題文の状況設定に合わせて適切なキーワードを紡ぎ出し、制限文字数内で簡潔に答える力も試されます。頻出の設問パターンと、部分点を確実にとるための解答テンプレートを紹介します。
「脆弱性の原因」を問われるパターン
問われ方の例:「下線部①の処理において、SQLインジェクションの脆弱性が生じる原因を40字以内で述べよ。」
解答の軸:「入力値が適切に処理されず、意図しないSQL文として解釈されるため。」
解説: 単に「エスケープ処理がないから」と書くよりも、その結果として「何が起こるのか(意図しないSQL文が組み立てられる)」まで言及することで、本質的な理解を示せます。問題文のコンテキストに応じて「文字列連結でSQL文を組み立てており、」という前提条件を付け加えると精度が上がります。
「具体的な対策手法」を問われるパターン
問われ方の例:「SQLインジェクションを防ぐための根本的な対策として、プログラム実装時にどのような仕組みを利用すべきか答えよ。」
解答の軸:「プレースホルダ(バインド変数)を利用してSQL文を組み立てる仕組み。」
解説: 「根本的な対策」という言葉がキーワードです。WAFの導入などは保険的対策に該当するため解答としては不十分です。「プレースホルダ」または「バインド変数」という専門用語を正確に使うことが求められます。
「想定される被害・影響」を問われるパターン
問われ方の例:「この脆弱性を悪用された場合、どのような情報漏えいの被害が想定されるか、表1のデータ項目を用いて述べよ。」
解答の軸:「(表1から具体的な項目を抜き出し)顧客のクレジットカード番号や暗証番号などの非公開情報が漏えいする被害。」
解説: 一般論として「個人情報が漏れる」と書くだけでは不十分です。問題文中の「表」や「図」から、漏えいしてはならない具体的なデータ名称(会員ランク、購入履歴、ハッシュ化されたパスワードなど)を拾い上げて組み込むことが重要です。これが「問題文を読めているか」の試金石となります。
演習①:攻撃文字列の構築を論理的に解く
ここからは記述問題を想定した例題で、知識を総動員して解答を導くプロセスを体験します。以下は特定の過去問そのものではなく、午後で頻出の出題形式を再現した本記事オリジナルの演習です。
例題:ECサイトの商品検索機能に潜む脆弱性
ECサイトを運営するA社では、商品検索機能に脆弱性が発見されました。WebアプリケーションはJavaで開発されており、利用者が入力した「商品カテゴリ(category_id)」を元にデータベースから商品を検索しています。脆弱性診断の結果、以下のSQL文組み立て処理に問題があると指摘されました。
String categoryId = request.getParameter("category_id");
String sql = "SELECT item_name, price FROM items WHERE category_id = '" + categoryId + "'";
// (中略)データベースでSQLを実行
診断員は「この実装では、攻撃者が category_id に特定の文字列を入力することで、意図しない全商品の情報が取得されてしまう可能性がある」と報告しました。
設問の意図を正確に読み解く
設問: 攻撃者が全商品の情報を取得するために、category_id に入力すると想定される文字列の例を、10文字以内で答えよ。
思考プロセス:
- プログラムは
category_idを文字列連結でSQL文に組み込んでいます。 - 攻撃者の目的は「全商品の情報を取得する」こと、つまり
WHERE句の条件を常に「真(True)」にすることです。 - 元のSQL文は
... WHERE category_id = '入力値'という構造です。 - 入力値を
' OR ''='(9文字)とした場合、組み立てられるSQL文は以下のようになります。
... WHERE category_id = '' OR ''=''
''='' は常に真のため、全レコードが取得されます。
- 文字数を確認し、10文字以内に収まっていることを確認します。
解答例と解説
解答例: ' OR ''='
この問題は、SQLインジェクションの古典的な原理を理解しているかを問う良問です。単に OR 1=1 というキーワードを暗記しているだけでは、前後のシングルクォーテーションの処理(文字列の終端と開始)を正しく構築できず、構文エラーになってしまいます。元のSQL文の構造を正確に把握し、「どこにどのような文字列を挿入すれば、全体として正しいSQL構文として成立し、かつ条件が常に真になるか」というパズルを解くような思考力が求められます。制限文字数という制約の中で最短の恒真式を組み立てる練習を繰り返しましょう。
演習②:多層防御と影響範囲の特定
もう一問、被害の拡大をどう防ぐかという設計レベルの知識が問われる例題を見てみましょう。こちらも出題形式を再現した本記事オリジナルの演習です。
例題:過剰権限のDBアカウントで拡大した被害
会員向けサービスを提供するB社では、会員情報を管理するDBサーバーとWebサーバーを運用しています。WebアプリケーションからDBサーバーへは、DB管理用のアカウント(全テーブルに対する全操作が可能な権限)を用いて接続していました。ある日、会員情報変更画面の入力フォームにSQLインジェクションの脆弱性が存在し悪用された形跡が発見されました。攻撃者は UNION SELECT を用いて、別テーブルに保存されていた「システム管理者パスワードのハッシュ値」を窃取した可能性が高いと判明しました。
設問の意図を正確に読み解く
設問: B社がWebアプリケーションからDBサーバーに接続する際のアカウント運用において、セキュリティ上の問題点を権限の観点から30字以内で述べよ。
思考プロセス:
- Webアプリケーションが「全テーブルに対する全操作が可能なDB管理用アカウント」を使ってDBに接続している点が問題です。
- セキュリティの基本原則である「最小権限の原則」に明らかに違反しています。会員情報変更画面であれば、必要なテーブルに対して必要な操作(SELECT、UPDATEなど)の権限だけを持たせるべきです。
- この過剰な権限設定があったため、脆弱性が存在した「会員情報変更画面」とは無関係の「システム管理者パスワード」が保存されているテーブルにまで
UNION SELECTでアクセスされてしまいました。
解答例と解説
解答例: 不必要なテーブルに対するアクセス権限まで付与されている点。(29文字)
この問題は脆弱性そのものの対策(プレースホルダなど)ではなく、脆弱性が存在してしまった場合の「被害の抑止(多層防御)」の観点を問うています。システム開発の現場では利便性を優先して、強力な権限を持つ単一アカウントで全DB操作を行う悪習が散見されます。試験ではこのようなアンチパターンを的確に指摘し、最小権限の原則に基づくアカウント分離という「あるべき姿」を理解しているかが問われます。SQLインジェクションの問題であっても、「ネットワーク構成」「権限管理」「ログ監視」といった周辺のセキュリティ対策と関連付けて考える習慣をつけてください。
記述解答の品質を高める3つの表現技術
過去問を繰り返し解くだけでなく、解答の「書き方」自体を洗練させることで得点率は大きく変わります。
制限文字数を逆算して構成を決める
記述問題では「○○字以内」という制約が必ず設けられています。解答を書き始める前に、その文字数で表現できる情報量を逆算する習慣をつけましょう。
- 20字以内:キーワード+簡潔な理由(1要素)
- 40字以内:原因+結果、または対策+効果(2要素)
- 60字以内:状況+問題点+あるべき姿(3要素)
文字数の制約は、解答に含めるべき要素の数を示すヒントでもあります。「20字で答えよ」という設問に3つの要素を詰め込もうとすれば、必然的に意味が伝わらない解答になります。
問題文のキーワードを積極的に転用する
記述問題の採点基準は、特定のキーワードが含まれているかどうかで部分点が振られることがほとんどです。問題文中に登場する技術用語(「プレースホルダ」「バインド変数」「最小権限」など)は、そのまま解答に使用してください。自分なりに言い換えると採点者に意図が伝わらないリスクがあります。
「原因→影響→対策」の三段論法を意識する
SQLインジェクションに関する記述問題の多くは、この三段論法のいずれかの部分を切り取って問います。設問を読んだ瞬間に「これは原因を問うている」「これは対策を問うている」と判断できれば、解答の方向性が即座に定まります。
例えば「どのような攻撃が可能か」という設問なら「影響」の部分を問われています。「どうすれば防げるか」なら「対策」です。設問の主語と述語を正確に読み取ることが、的外れな解答を防ぐ最大の武器になります。
【午後対策・練習問題】SQLインジェクション完全攻略(全10問)
記事で解説した「発生メカニズム」「根本的対策」「多層防御」の理解度をチェックするための練習問題です。情報処理安全確保支援士試験の午後・記述問題で狙われやすいポイントを凝縮しました。各選択肢の詳しい解説も用意していますので、以下の練習問題で本記事の理解度を確認してみましょう。
まとめ:SQLインジェクションを得点源にする
「SQLインジェクション攻撃を防ぐ方法はどれか」という午前IIの4択も、午後の記述問題も、問われている本質は常に以下の3点に帰結します。私がCIO時代にWAFを導入できず、Webサーバー側のハードニングで泥臭く守っていた頃から本質は変わっていません。守りの本丸は、入力値をSQLの構文ではなく「データ」として扱わせるアプリケーション側の設計です。
- 根本原因は「データとコードの混同」であると理解する。 文字列連結でSQL文を組み立てると、入力値がSQL構文の一部として解釈されてしまうことを自分の言葉で説明できるようにしましょう。
- 根本的対策は「プレースホルダ(バインド変数)」による構文の固定化であると説明できるようにする。 WAFやエラーメッセージの隠蔽は保険的対策であり、混同しないことが重要です。
- 過去問演習では、元のSQL文の構造を正確に把握し、攻撃者の意図をパズルのように組み立てる訓練をする。 文字数制約も含めて解答を完成させる練習が、本番での得点力に直結します。
- 権限最小化やWAFなどの「多層防御」の視点を常に持つ。 SQLインジェクションの設問であっても、権限管理やネットワーク構成と関連付けて考える習慣が合否を分けます。
暗記に頼らず論理的な思考プロセスを磨き上げることで、SQLインジェクションの設問は必ず強力な得点源となります。午後試験突破に向けて、本記事の解法テクニックを実践してください。
プレースホルダの仕組み(静的/動的の違い、エスケープとの差、言語別実装)を技術的に掘り下げた解説は「SQLインジェクション対策はプレースホルダが正解|プリペアドステートメントの仕組みを完全解説」を参照。
本記事は情報処理安全確保支援士(SC)試験対策を目的として作成しています。
参考資料
- IPA「安全なウェブサイトの作り方」1.1 SQLインジェクション
- 情報セキュリティスペシャリスト 平成22年秋期 午前II 問8「SQLインジェクション攻撃を防ぐ方法」
- 情報処理安全確保支援士 令和5年春期 午前II 問17 SQLインジェクション対策
- SQLインジェクション対策の本命「プレースホルダ」を仕組みから理解する(当サイト関連記事)
テンプレート集
+おまけ:毎日1通の無料メール講座つき。登録した日が「1日目」、図解と論理で16週間かけて基礎も固まります。