情報セキュリティマネジメント 2023年 科目A 問07
問題文
Webアプリケーションにおけるセキュリティ上の脅威とその対策に関する記述のうち、適切なものはどれか。
選択肢
ア:OSコマンドインジェクションを防ぐために、Webアプリケーションが発行するセッションIDに推測困難な乱数を使用する。
イ:SQLインジェクションを防ぐために、Webアプリケーション内でデータベースへの問合せを作成する際にプレースホルダを使用する。(正解)
ウ:クロスサイトスクリプティングを防ぐために、Webサーバ内のファイルを外部から直接参照できないようにする。
エ:セッションハイジャックを防ぐために、Webアプリケーションからシェルを起動できないようにする。
🔒 解説は解答すると表示されます
Webアプリ脅威対策【情報セキュリティマネジメント解説】
正解の理由
選択肢のうち、SQLインジェクション(SQL Injection:データベースへの問い合わせ文に悪意ある文字列を混入させて不正に操作する攻撃)を防ぐ対策として最も有効なのは、Webアプリケーションがデータベースへ問合せを作成する際にプレースホルダ(プレースホルダ/プレペアードステートメント:値と命令を分離して扱う仕組み)を使う方法です。これがイの記述です。
プレースホルダ(パラメータ化クエリ、prepared statement)を使うと、ユーザ入力は「値」としてデータベースに渡され、SQL文の一部(命令)として解釈されません。したがって、攻撃者がクエリ文を壊して実行させることができなくなり、SQLインジェクションを効果的に防げます。
解法ステップ
- 各選択肢が「どの脅威」を対象にしているかを確認する(OSコマンドインジェクション、SQLインジェクション、XSS、セッションハイジャック)。
- その脅威に対して提示された対策が直接的かつ一般的に有効かを考える。
- 有効であれば正答候補とし、無関係・不十分・誤解を招く対策は除外する。
- 最後に、実務での具体的な実装例や注意点で裏付ける。
この問題では、SQLインジェクション対策としてプレースホルダを使うことが直接的に有効なので、イが正解です。
選択肢別の誤答解説
-
ア: OSコマンドインジェクションに対する記述として不適切です。
- OSコマンドインジェクション(サーバ上で意図しないOSコマンドが実行される攻撃)を防ぐには、外部コマンドを呼び出さない設計、入力のホワイトリスト(許可リスト)検証、シェルを経由しない安全なAPIの使用が重要です。
- セッションIDの乱数化は「セッションの推測防止・セッション固定化の対策」であり、OSコマンドインジェクションとは無関係です。
-
イ: 正しい。
- プレースホルダ(prepared statements / parameterized queries)は、SQL文の構造と値を分離するため、ユーザ入力がSQL構文として解釈されることを防ぎます。実務でも最も基本的かつ推奨される対策です。
-
ウ: クロスサイトスクリプティング(XSS:利用者のブラウザ上で攻撃者のスクリプトが実行される攻撃)への対策として不適切です。
- 「Webサーバ内のファイルを外部から直接参照できないようにする」ことはアクセス制御の一つで、ファイルの不正ダウンロードや情報漏洩を減らしますが、XSSはページに挿入されたスクリプトがブラウザで実行される問題であり、出力時のエスケープ(HTMLエスケープ)、Content Security Policy(CSP:外部スクリプトの読み込み制御)、入力検証が主な対策です。
-
エ: セッションハイジャック対策として誤りです。
- 「Webアプリケーションからシェルを起動できないようにする」はサーバ側のコマンド実行リスク低減にはなるかもしれませんが、セッションハイジャック(他人が利用者のセッションを乗っ取る攻撃)を防ぐためにはTLS(通信の暗号化)、セッションIDの十分なランダム化、Cookie属性(Secure, HttpOnly, SameSite)の設定、セッションIDの再生成やタイムアウトが有効です。
よくある誤解
- セッションIDのランダム化はすべての攻撃を防ぐ:セッションIDの強化は重要ですが、盗聴やXSSなどで盗まれれば意味がありません。TLSやHttpOnlyなどの併用が必要です。
- プレースホルダを使えば「何もしなくてよい」わけではない:プレースホルダはSQLインジェクションに強力ですが、論理的エラーや権限管理の不備、バッチ処理のミスは別問題です。
- XSS対策は「ファイルの参照制限」で解決する:XSSは主に出力側の処理(サニタイズ/エスケープ)なので、別の対策が必要です。
補足コラム
- プレースホルダの簡単なコード例(Python、sqlite3):
import sqlite3
conn = sqlite3.connect('example.db')
cur = conn.cursor()
# ユーザ入力を直接文字列連結しない
user_input = "some value"
# プレースホルダを使う(値は自動でエスケープされる)
cur.execute("SELECT * FROM users WHERE name = ?", (user_input,))
rows = cur.fetchall()
- OSコマンドインジェクション対策のポイント:
- 外部コマンド実行を避ける。どうしても使うなら引数をエスケープせずに渡さない、言語の安全APIを使う。入力はホワイトリストで検証する。
- XSS対策のポイント:
- 出力時に適切にエスケープ(HTMLエスケープ)、CSPの導入、CookieにHttpOnlyを設定してJavaScriptから読み取れないようにする。
- セッションハイジャック対策のポイント:
- HTTPS必須、CookieにSecure/HttpOnly/SameSite属性、短めの有効期限と操作時のID再生成、異常なアクセス(IPやUAの急変)での強制再認証。
実務での運用イメージ:開発ルールとして「DBアクセスは全てプレースホルダで実装」「外部コマンド呼び出しは設計審査で厳格に管理」「入力と出力の担当を明確にしてレビューする」といったガイドラインを作ると現場で運用しやすくなります。
FAQ
Q. プレースホルダはどの言語でも使える?
A. ほとんどの主要な言語のDBライブラリ(JavaのJDBC、PythonのDB-API、PHPのPDOなど)がサポートしています。ただし記法(? や :nameなど)はライブラリによって異なります。
A. ほとんどの主要な言語のDBライブラリ(JavaのJDBC、PythonのDB-API、PHPのPDOなど)がサポートしています。ただし記法(? や :nameなど)はライブラリによって異なります。
Q. プレースホルダだけで完全に安全になる?
A. SQLインジェクションに対してはほぼ十分ですが、アプリの認可・認証の不備やログ管理の不足など、別の脅威は別対策が必要です。
A. SQLインジェクションに対してはほぼ十分ですが、アプリの認可・認証の不備やログ管理の不足など、別の脅威は別対策が必要です。
Q. 既存コードが文字列連結でSQLを作っている場合は?
A. 段階的に修正します。まず重要な箇所(ログイン、決済、権限変更)からプレースホルダに置き換え、静的解析ツールやセキュリティテストで検出する運用を導入しましょう。
A. 段階的に修正します。まず重要な箇所(ログイン、決済、権限変更)からプレースホルダに置き換え、静的解析ツールやセキュリティテストで検出する運用を導入しましょう。
関連キーワード: SQLインジェクション、プレースホルダ、プレペアードステートメント、クロスサイトスクリプティング(XSS)、OSコマンドインジェクション、セッションハイジャック、Cookie属性、Content Security Policy, Prepared Statement, パラメータ化クエリ

\ せっかくなら /
情報セキュリティマネジメントを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

