はじめに
Webアプリケーションにおけるセキュリティリスクの一つに「SQLインジェクション(SQL Injection)」がある。
この攻撃手法は、悪意のあるSQL文をシステムに注入し、不正にデータを取得・改ざん・削除するといった深刻な影響を及ぼす。
SQLインジェクションは、適切な対策を講じることで防ぐことが可能だ。
本記事では、基本情報技術者試験(令和6年)科目A 問10 の問題を通じて、SQLインジェクションの仕組みと対策を解説していく。
基本情報技術者試験(科目A)問10の問題
試験問題
SQLインジェクションの対策として,有効なものはどれか。
ア. URLをWebページに出力するときは,”http://”や”https://”で始まるURLだけを許可する。
イ. 外部からのパラメータでWebサーバ内のファイル名を直接指定しない。
ウ. スタイルシートを任意のWebサイトから取り込めるようにしない。
エ. プレースホルダを使って命令文を組み立てる。
解答と解説
この問題の正解は 「エ. プレースホルダを使って命令文を組み立てる。」 である。では、それぞれの選択肢が何を意味するのか詳しく見ていこう。
1. SQLインジェクション対策としてのプレースホルダ【正解:エ】
プレースホルダ(Placeholder) は、SQL文においてユーザーの入力値を安全に扱うための仕組み である。
SQLインジェクションは、ユーザーが入力したデータがそのままSQL文に埋め込まれることで発生する。例えば、以下のようなコードがあるとする。
危険なSQLの例
$uid = $_POST["userid"];
$sql = "SELECT * FROM USER WHERE uid = '$uid'";
$result = $db->query($sql);
このコードでは、ユーザーが次のような入力をすると、不正なSQL文が実行されてしまう。
' OR '1'='1
すると、SQL文は以下のようになり、全てのユーザー情報が取得できてしまう。
SELECT * FROM USER WHERE uid = '' OR '1'='1'
このような攻撃を防ぐために、プレースホルダを使用する。
プレースホルダを使った安全なSQL
$uid = $_POST["userid"];
$sql = "SELECT * FROM USER WHERE uid = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$uid]); // ? に値をバインドする
プレースホルダのメリット
- SQL文とユーザーの入力値を分離 することで、悪意のあるSQL文を無効化できる
- エスケープ処理を自動的に行う ため、SQLインジェクションを防げる
この方法を適用することで、SQLインジェクションの根本的な対策 となるため、「エ」が正解である。
2. 各選択肢の説明
ア. URLの制限【誤り】
「URLをWebページに出力するときは,”http://”や”https://”で始まるURLだけを許可する。」
この対策は、クロスサイトスクリプティング(XSS) に対するものであり、SQLインジェクションとは異なる。
XSSの危険性
- 攻撃者が悪意のあるJavaScriptを埋め込むことで、ユーザーの情報を盗み出す
- 例えば、次のようなリンクを埋め込まれると、悪意のあるスクリプトが実行される
<a href="javascript:alert('XSS Attack!')">Click here</a>
このような攻撃を防ぐために、”http://” や “https://” で始まるURLだけを許可する ことは、XSS対策としては有効だが、SQLインジェクションの対策ではないため、誤り である。
イ. ファイル名の直接指定を避ける【誤り】
「外部からのパラメータでWebサーバ内のファイル名を直接指定しない。」
この対策は、ディレクトリトラバーサル攻撃 に対するものであり、SQLインジェクションとは異なる。
ディレクトリトラバーサル攻撃
- Webアプリのファイル操作において、外部から指定されたファイル名をそのまま利用すると、攻撃者によりシステム内部の機密ファイルが閲覧される可能性がある
- 例えば、次のようなコードがあるとする
$filename = $_GET["file"];
include("/var/www/html/" . $filename);
- ここで、攻撃者が次のようなリクエストを送ると、機密ファイルが閲覧される
ディレクトリトラバーサル攻撃の対策としては、ユーザーの入力を検証し、指定できるファイル名を制限することが重要 だ。しかし、SQLインジェクションの対策ではないため、誤り である。
ウ. スタイルシートの制限【誤り】
「スタイルシートを任意のWebサイトから取り込めるようにしない。」
この対策は、CSSインジェクション に対するものであり、SQLインジェクションとは異なる。
CSSインジェクションの危険性
- 外部のスタイルシートを利用して、Webページの表示を改ざんしたり、情報を盗み出す攻撃
- 例えば、攻撃者が次のようなスタイルを適用すると、パスワード入力欄を透明にして、ユーザーが気づかずに入力するよう誘導できる
input[type="password"] {
visibility: hidden;
background: url("http://malicious-site.com/steal.png");
}
- このような攻撃を防ぐために、外部サイトのスタイルシートの取り込みを制限することが有効 だが、SQLインジェクションの対策ではないため、誤り である。
SQLインジェクション対策のまとめ
対策方法 | 防げる攻撃 | 主な技術 |
---|---|---|
プレースホルダを使用 | SQLインジェクション | プレースホルダ (? や :param など) |
ユーザー入力のバリデーション | SQLインジェクション、XSS、ディレクトリトラバーサル | 入力チェック (preg_match , htmlspecialchars ) |
適切な権限設定 | SQLインジェクション、ディレクトリトラバーサル | データベースユーザーの権限制限 |
ファイルのハッシュ検証 | ディレクトリトラバーサル、改ざん攻撃 | hash_file() |
まとめ
今回の試験問題では、「SQLインジェクションの対策として有効なもの」として、「プレースホルダを使って命令文を組み立てる。」(エ) が正解だった。
SQLインジェクションはアプリケーションのセキュリティ上の重大な脆弱性 であり、適切な対策が求められる。
特に、プレースホルダを使ったSQLの組み立て は、SQLインジェクションを防ぐ最も確実な方法である。
開発者は、セキュアコーディングの重要性を理解し、安全なアプリケーションを構築することが求められる。
コメント