情報処理安全確保支援士過去問題 令和4年春期 午後Ⅰ 問1
⇄問題PDFと解説を画面2分割で開く⇱問題PDF設問1
解答入力欄
- a:
解答例・解答の要点
- ア
- プレースホルダ
- a:改行コード
解説
- HTTPヘッダーインジェクションは、動的にHTTPヘッダーを生成するシステムにおいて、HTTPヘッダー内に改行コードなどを不正挿入することによって、不正なヘッダー情報を挿入したり、任意の記述をメッセージボディに挿入したりする攻撃です。
HTTPヘッダーは、1行に1つを記述することになっていて改行がヘッダー同士の区切りとなっています。HTTPのパラメタで改行を意味する文字列は「%0D%0A」です。これは改行コード「¥r¥n(ASCIIコードの0x0d 0x0a)」をパーセントエンコーディング(URLエンコーディング)したものです。したがって「ア:%0D%0A」が正解です。攻撃者は「%0D%0A」のあとにSet-Cookieなどの任意のHTTPヘッダーフィールドを挿入して、セッションフィクセーションなどの攻撃を実行します。
なお、「イ:%20」は空白、「ウ:<br>」はHTMLの改行タグ、「エ:<p>」はHTMLの段落(Paragraph)タグです。
∴ア:%0D%0A - SQLインジェクション攻撃は、利用者から入力情報を基にSQL文を組み立てる処理に問題がある場合、攻撃者が入力したSQLがデータベース上にてそのまま実行されてしまい、データベースに蓄積された情報の改ざんや非公開情報の閲覧ができてしまう攻撃です。
解決策として、IPAの「安全なウェブサイトの作り方 改訂第7版」では、SQL文の組み立てはすべてプレースホルダで実装する方法と特別な意味を持つ記号文字(「`」や「¥」)をエスケープ処理する方法が紹介されています。プレースホルダとは、利用者入力部分に特殊文字(「?」など)を割り当てたSQLのひな形を用意し、特殊文字部分には実行時にエスケープ処理された値を割り当てる仕組みです。 下線②の「変数の場所を示す?記号」とは、プレースホルダのことを指します。したがって解答は「プレースホルダ」です。
∴プレースホルダ - 〔aについて〕
メールヘッダーインジェクションは、ユーザーがメールアドレスと本文を入力してメールを送信するシステムにおいて、攻撃者がメールヘッダーに改行コードとメールヘッダーを不正挿入することで、管理者が意図しない宛先への送信や本文の改ざんなどができる攻撃です。改行コードを悪用した攻撃という意味ではHTTPヘッダーインジェクションと同じです。IPAの「安全なウェブサイトの作り方 改訂第7版」では、対策として、項番3の(1)と(2)の対策のほかに「外部からの入力の全てについて、改行コードを削除する」ことが紹介されています。したがって、空欄aには「改行コード」が入ります。
∴a=改行コード
設問2
解答入力欄
- b:
- c:
解答例・解答の要点
- クエリ文字列のidに,未参加のプロジェクトのプロジェクトIDを指定する。
- ・プロジェクトを示すパラメタを外部から指定できないから
・セッション情報からプロジェクトIDを取得するから
- b:ウ
- c:stmt
解説
- 情報選択機能にて情報を選択する方法を確認してみると、方法1に「GETリクエストのクエリ文字列に,"id=プロジェクトID"の形式で指定する。情報選択機能は,クエリ文字列からプロジェクトIDを取得する」とあります。なお、クエリ文字列とはURLの「?」に続く、パラメタ名=値の部分をいいます。表2の項番3の「操作の結果」に示されているURLで言えば「no=1001」がクエリ文字列です。
情報選択機能は、表示するプロジェクトを識別するのにクエリ文字列の情報をそのまま使用しています。「プロジェクトを識別するプロジェクトIDを連番で採番する」とあるので、その規則性を容易に推測できてしまいます。また、GETリクエストのクエリ文字列は、Webブラウザなどから容易に書き換えることが可能です。自身で利用者IDでログイン後、Sシステムが発行したリンクのURLを参照し、クエリ文字列のプロジェクトIDの値を変更することで、指定したプロジェクトの情報を取得できてしまう状態にあります。したがって、未参加のプロジェクトに参加しているように偽るためには、クエリ文字列のidの値として未参加のプロジェクトIDとすればよいです。
∴クエリ文字列のidに,未参加のプロジェクトのプロジェクトIDを指定する。 - 下線④は「方法1の脆弱性が方法2で解決される」とあります。方法1の脆弱性は、問題文にもあるとおり、情報選択機能がクエリ文字列で受け取ったプロジェクトIDをチェックせずに利用していることに起因します。その脆弱性が解決されたとあるので、クエリ文字列ではなく別の方法でプロジェクトIDを取得していると考えます。
方法1と方法2の違いを確認すると、方法1ではクエリ文字列からプロジェクトIDを取得しますが、方法2ではセッション情報に格納された利用者情報から取得します。セッション情報とは通信の継続性を保つためにサーバに保持される情報です。ログイン時に利用者情報をセッション情報に記録しておき、リクエストがあったときにその利用者情報からデータベース上のプロジェクトIDを取得するようにすれば、外部からのパラメタの指定によることなく、参加しているプロジェクトの情報を取得することができます。これにより、未参加のプロジェクトの情報が表示される脆弱性が解決されます。
∴・プロジェクトを示すパラメタを外部から指定できないから
・セッション情報からプロジェクトIDを取得するから - 〔bについて〕
空欄bを含むソースコードは以下の一文です。空欄には変数 stmt の型名が入ります。java.sql.b stmt = con.preparedStatement(sql);7行目のSQL文にプレースホルダ「?」が含まれていること、preparedStatementが記述されていることから、プレースホルダのため事前にSQLを渡していることがわかります。Javaでプレースホルダを利用するには、以下の手順を踏みます。- 文字列型の変数にプレースホルダを含むSQLのひな形を格納する(7行目)。
- java.sql.Connection の preparedStatement メソッドを用いて PrepareStatement オブジェクトを生成する(8行目)
なお、「ア:Connection」はデータベースの接続を保持するオブジェクト、「イ:DriverManager」はデータベースに接続するためのクラス、「エ:Statement」は実行時にSQLを渡して実行するためのオブジェクトです。
∴b=ウ:PreparedStatement - 〔cについて〕
空欄cを含むソースコードは以下の一文です。空欄には setInt を呼び出すオブジェクト名が入ります。c.setInt(1, projectId);このコードは7行目のプレースホルダにプロジェクトIDの値を割り当てるためのものです。int型の変数の値をプレースホルダに割り当てるには、PreparedStatement インタフェースの setInt メソッドを使用します(String型の文字列は setString)。8行目でSQLステートメントが変数 stmt に格納されているため、操作対象となる PreparedStatement インタフェースのオブジェクトは「stmt」となります。
∴c=stmt
設問3
解答入力欄
- d:
解答例・解答の要点
- d:情報番号 = ? AND プロジェクトID = ?
解説
〔dについて〕
空欄dを含むSQL文は次のとおりです。WHERE句の後ろですのでレコードの抽出条件が入ることがわかります。
図1のE-R図を再確認して、外部キーであるプロジェクトIDとの完全一致が抽出条件に使えるか検討します。プロジェクトIDは7行目で変数 projectId に格納されています。利用者が参加するプロジェクトのプロジェクトIDは、設問2の(2)の解説にて述べたとおり、セッション情報から取得できます。また、セッション情報に格納されているパラメタは外部から指定できません。クエリ文字列の情報番号を偽装して未参加のプロジェクトの情報を閲覧しようとしても、プロジェクトIDは偽装できません。したがって、情報管理テーブルの情報番号とプロジェクトIDの両方が完全一致する、という条件で絞り込めば脆弱性を解消できます。よって、プロジェクトIDの完全一致も抽出条件として利用します。
両方が一致するときに取得したいので、各抽出条件は「AND」でつなぎます。図3の9行目と10行目でプリペアドステートメントを用意して実行しているため、情報番号とプロジェクトIDの値の部分にはプレースホルダの「?」を割り当てます。したがって、空欄dには「情報番号 = ? AND プロジェクトID = ?」が当てはまります。
∴d=情報番号 = ? AND プロジェクトID = ?
空欄dを含むSQL文は次のとおりです。WHERE句の後ろですのでレコードの抽出条件が入ることがわかります。
SELECT 情報番号, 情報名, 情報内容 FROM 情報管理テーブル WHERE d
まず、情報表示機能の処理の流れを表2より確認します。- 項番2:情報番号"1001"の"コーディングルール"をプルダウンメニューから選択する
- 項番3:情報番号"1001"がクエリ文字列の"no"に格納され、情報番号"1001"のコーディングルールを表示する
図1のE-R図を再確認して、外部キーであるプロジェクトIDとの完全一致が抽出条件に使えるか検討します。プロジェクトIDは7行目で変数 projectId に格納されています。利用者が参加するプロジェクトのプロジェクトIDは、設問2の(2)の解説にて述べたとおり、セッション情報から取得できます。また、セッション情報に格納されているパラメタは外部から指定できません。クエリ文字列の情報番号を偽装して未参加のプロジェクトの情報を閲覧しようとしても、プロジェクトIDは偽装できません。したがって、情報管理テーブルの情報番号とプロジェクトIDの両方が完全一致する、という条件で絞り込めば脆弱性を解消できます。よって、プロジェクトIDの完全一致も抽出条件として利用します。
両方が一致するときに取得したいので、各抽出条件は「AND」でつなぎます。図3の9行目と10行目でプリペアドステートメントを用意して実行しているため、情報番号とプロジェクトIDの値の部分にはプレースホルダの「?」を割り当てます。したがって、空欄dには「情報番号 = ? AND プロジェクトID = ?」が当てはまります。
∴d=情報番号 = ? AND プロジェクトID = ?