SQLインジェクションに効く対策はどれか、攻撃と対策の対応で見分ける
基本情報技術者試験 令和6年度 問10 / セキュリティ › セキュリティ実装技術
過去問にチャレンジ
SQLインジェクションの対策として,有効なものはどれか。
- ア
URL をWeb ページに出力するときは,“http://”や“https://”で始まるURL だけを許可する。
- イ
外部からのパラメータでWebサーバ内のファイル名を直接指定しない。
- ウ
スタイルシートを任意のWebサイトから取り込めるようにしない。
- エ
プレースホルダを使って命令文を組み立てる。
会話形式の解説
講師今回はSQLインジェクションに効く対策を選ぶ問題です。選択肢はどれもWebアプリケーションのセキュリティ対策として正しそうに見えます。なので「その対策はどの攻撃を防ぐためのものか」に注目して読んでください。
受験者全部もっともらしく見えて迷いました。どれも「外部から来たものを信用しない」という話に思えます。
講師そう見えますよね。まず、SQLインジェクションがどういう攻撃かを確認しましょう。データベースに送るSQL文に利用者の入力値を組み込むとき、その入力値がSQLの命令の一部として解釈されてしまう。そこを突く攻撃です。
受験者ということは、有効な対策は「SQL文をどう組み立てるか」に関わるもの、ということですか。
講師その通りです。その観点で、URLを「http://」や「https://」で始まるものだけに限るという選択肢を見てみましょう。これは何のための対策だと思いますか。
受験者URLの話なので、Webページへの出力に関係がありそうです。SQL文とは関係なさそうに見えます。
講師はい。これはクロスサイトスクリプティング、略してXSSへの対策です。XSSは、ページにスクリプトを埋め込んで実行させる攻撃です。「javascript:」で始まるURLがリンクに入っていると、クリックしたときにスクリプトが動くおそれがあります。それを防ぐのが目的なので、SQL文の組立ては安全になりません。
受験者外部からのパラメータでサーバ内のファイル名を直接指定しない、という選択肢はどうでしょうか。これも入力値の扱いの話なので、少し迷いました。
講師確かに入力値の話ですが、扱う対象はファイルです。これはディレクトリトラバーサルへの対策です。ファイル名を外部から指定できる作りだと、公開するつもりのないファイルを読まれるおそれがあります。ファイルへのアクセスを守るもので、SQL文の問題は解決しません。
受験者スタイルシートを任意のサイトから取り込めないようにする、というのも別の攻撃への対策ですか。
講師はい、CSSインジェクションへの対策です。外部のスタイルシートを埋め込まれると、コンテンツを非表示にされる、要素を追加される、属性値を外部に取得されるといった被害が起こりえます。ただ、データベースに送るSQL文とは関係がありません。
受験者残るのはプレースホルダを使って命令文を組み立てる、という選択肢ですね。プレースホルダが何か、あまり分かっていません。
講師プレースホルダは、SQL文の中で入力値が入る位置に置いておく記号です。先にSQL文の形を決めておき、値は後から別に渡します。こうするとSQL文の構造と入力値が分けて扱われるので、渡した値はデータとしてだけ処理され、命令として解釈されることはありません。
受験者入力値を文字列としてつなげてSQL文を作ると命令に混ざってしまう。プレースホルダなら値と命令が分かれているので防げる、ということですね。
講師よく整理できています。補足すると、エスケープ処理や入力値の検証もSQLインジェクション対策として挙げられますが、根本的な対策はプレースホルダでSQL文を組み立てることです。データベースのアカウント権限を最小限にするのは、被害を小さくするための補助的な対策と考えてください。
受験者ほかの攻撃への正しい対策が誤りの選択肢として並ぶので、攻撃と対策をセットで覚えておくのが大事だと分かりました。
まとめ
SQLインジェクションは、入力値がSQL文の命令の一部として解釈されてしまうことで成り立つ攻撃で、有効な対策はプレースホルダを使ってSQL文を組み立てることです。プレースホルダを使うとSQL文の構造と入力値が分けて扱われ、入力値はデータとしてだけ処理されます。URLスキームの制限はXSS、ファイル名を直接指定させないことはディレクトリトラバーサル、外部スタイルシートの制限はCSSインジェクションへの対策です。エスケープ処理や入力値の検証も対策として挙げられますが、根本的な対策はプレースホルダの利用で、アカウント権限の最小化は被害を小さくするための補助的な対策です。
解答・解説
正解はエです
この問題のテーマ
Webアプリケーションへの代表的な攻撃とその対策の組合せの中から、SQLインジェクションに効く対策を選べるかを問う問題です。
解き方の考え方
まず、SQLインジェクションが「入力値がSQL文の命令として解釈されてしまう」ことで成り立つ攻撃だと押さえます。そうすると、有効な対策は「SQL文の組立て方」に関わるものに限られるとわかります。次に各選択肢が何の攻撃への対策なのかを見分け、SQL文の組立てに関係しないもの(XSS、ディレクトリトラバーサル、CSSインジェクションへの対策)を外していけば、正解にたどり着けます。
選択肢ごとの解説
- ×ア URL をWeb ページに出力するときは,“http://”や“https://”で始まるURL だけを許可する。出力するURLを「http://」や「https://」で始まるものに限るという説明は、クロスサイトスクリプティング(XSS)への対策です。「javascript:」で始まるURLがリンクに埋め込まれていると、クリックしたときにスクリプトが実行されるおそれがあり、それを防ぐ目的で行います。URLのスキームを制限しても、SQL文の組立てが安全になるわけではありません。
- ×イ 外部からのパラメータでWebサーバ内のファイル名を直接指定しない。外部からのパラメータでWebサーバ内のファイル名を直接指定させないという説明は、ディレクトリトラバーサルへの対策です。ファイル名を外部から指定できる作りだと、公開するつもりのないファイルの内容を読まれるおそれがあります。この対策はファイルへのアクセスに関するもので、SQL文の組立てや実行の問題は解決しません。
- ×ウ スタイルシートを任意のWebサイトから取り込めるようにしない。任意のWebサイトからスタイルシートを取り込めないようにするという説明は、CSSインジェクションへの対策です。外部のスタイルシートを埋め込まれると、ページの見た目を書き換えられるなどの被害が起こりえます。ただし、データベースに送るSQL文とは関係がないので、SQLインジェクションの防止策にはなりません。
- ○エ プレースホルダを使って命令文を組み立てる。プレースホルダを使って命令文を組み立てる方法は、SQLインジェクションへの有効な対策です。プレースホルダは、SQL文の中で入力値が入る位置に置く記号です。この方法ではSQL文の構造と入力値が分けて扱われ、渡した値はデータとしてだけ処理され、命令として解釈されることはありません。SQL文の組立てをすべてプレースホルダで実装することが、根本的な対策とされています。
補足
この種の問題は、ほかの攻撃への正しい対策が誤りの選択肢として並ぶことが多いので、「その対策はどの攻撃を防ぐためのものか」を対応づけて覚えておくと解きやすくなります。エスケープ処理や入力値の検証もSQLインジェクション対策として挙げられますが、根本的な対策はプレースホルダを使ってSQL文を組み立てることです。データベースのアカウント権限を最小限にするといった対策は、被害を小さくするための補助的なものと位置づけられます。
POINT
- SQLインジェクションは、入力値がSQL文の命令の一部として解釈されてしまうことで成り立つ攻撃です。
- 入力値を文字列連結でSQL文に組み込むと、入力が命令に混ざる危険があります。
- プレースホルダを使うとSQL文の構造と入力値が分離され、入力値はデータとして扱われます。
- URLスキームの制限はXSS、ファイル名の直接指定の禁止はディレクトリトラバーサル、外部スタイルシートの制限はCSSインジェクションへの対策です。
