【情報処理安全確保支援士試験 令和4年度 春期 午後1 問1 No.2】

情報処理安全確保支援士試験 令和4年度 春期 午後1 問1

【出典:情報処理安全確保支援士試験 令和4年度 春期 午後1 問1(一部、加工あり)】

[Sシステムの改修におけるアクセス制御要件の追加]
 開発部で新しいプロジェクトを立ち上げることになり、開発部の各プロジェクト内の情報共有を強化することにした。開発部は、次のようにSシステムを改修する方針とした。

  • 社内ルールだけでなく、各プロジェクトの計画書や各種の設計情報を各プロジェクト内で共有できるようにする。
  • 各プロジェクトの計画書や各種の設計情報については、情報が表示できる利用者を、情報の作成者と同じプロジェクトに参加する利用者に限定できるようにする。

 なお、開発部員は、一時的には一つのプロジェクトだけに参加する。同時に複数のプロジェクトには参加しない。
 開発部のDさんが、Sシステム改修の担当者に任命され、利用者のアクセス制御を次のように設計した。

  • プロジェクトを識別するプロジェクトIDを連番で採番する。
  • 利用者IDそれぞれに対して、その利用者が参加するプロジェクトのプロジェクトIDを登録しておく。
  • Sシステムに格納される各情報に、作成者の参加するプロジェクトを示すプロジェクトIDをあらかじめ付与しておく。
  • プロジェクトIDを次に示す方法で取得し、そのプロジェクトIDを用いてアクセス制御する。

方法1:ログイン時にその利用者IDに対して登録されているプロジェクトIDを取得し、GETリクエストのクエリ文字列に、”id=プロジェクトID”の形式で指定する。情報選択機能は、クエリ文字列からプロジェクトIDを取得する。

[情報選択機能の脆弱性]
 Sシステム改修後の脆弱性検査で、情報セキュリティ部は、プロジェクトの情報番号と情報名を、そのプロジェクトには参加していない利用者が、③そのプロジェクトに参加しているかのように偽ってリスト可能であるという脆弱性を指摘した。これは、情報選択機能においてクエリ文字列で受け取ったプロジェクトIDをチェックせずに利用していることに起因していた。この指摘を受けて、Dさんは、プロジェクトIDの取得方法として、次に示す別の方法を提示した。

方法2:情報選択機能の利用時に、セッション情報から利用者情報を取得する。情報選択機能は、当該利用者情報からプロジェクトIDを取得する。

 情報セキュリティ部は、④方法1の脆弱性が方法2で解決されることを確認した。Dさんは、プロジェクトIDの取得方法を方法2に修正した。
 情報選択機能及び情報表示機能が参照するデータベースのE-R図を図1に、修正後の情報選択機能のソースコードを図2に示す。

下線③について、未参加のプロジェクトに参加しているかのように偽るための操作を、40字以内で具体的に述べよ。:クエリ文字列のidに、未参加のプロジェクトのプロジェクトIDを指定する。

Sシステム改修後の脆弱性検査で、情報セキュリティ部は、プロジェクトの情報番号と情報名を、そのプロジェクトには参加していない利用者が、③そのプロジェクトに参加しているかのように偽ってリスト可能であるという脆弱性を指摘した。
 方法1の内容で、未参加のプロジェクトに参加しているかのように偽るための操作が可能か確認していきます。
 「方法1:ログイン時にその利用者IDに対して登録されているプロジェクトIDを取得し、GETリクエストのクエリ文字列に、”id=プロジェクトID”の形式で指定する。情報選択機能は、クエリ文字列からプロジェクトIDを取得する。
 ログイン時に取得するプロジェクトIDは利用者IDに紐づいていて、他のプロジェクトIDを取得することはできないようです。
 ログイン後に表示される画面では、例えば各種情報を示すリンクが表示され、そのリンク先には当該プロジェクトIDをGETリクエストのクエリ文字列に指定するとのことです。
 例えば「https://www.sample.com/select?id=xxx」のようにURL欄にプロジェクトIDが表示されます。
 これはURL欄で「id=xxx」の部分を書き換えることが可能ということです。
 したがって、未参加のプロジェクトに参加しているかのように偽るための操作としては、クエリ文字列のidに、未参加のプロジェクトIDを指定することが想定できます。

下線④について、方法1の脆弱性が方法2で解決されるのはなぜか。30字以内で述べよ。:プロジェクトを示すパラメタを外部から指定できないから/セッション情報からプロジェクトIDを取得するから

情報セキュリティ部は、④方法1の脆弱性が方法2で解決されることを確認した。
 方法1の脆弱性について、「これは、情報選択機能においてクエリ文字列で受け取ったプロジェクトIDをチェックせずに利用していることに起因していた。」と指摘されています。
 ここでいうプロジェクトIDのチェックとは、利用者IDに紐づくプロジェクトIDであるかどうかのチェックになり、利用者で任意に変更できるプロジェクトIDをチェックしていないことが問題でした。
 これを「方法2:情報選択機能の利用時に、セッション情報から利用者情報を取得する。情報選択機能は、当該利用者情報からプロジェクトIDを取得する。」に変更します。
 セッション情報については、表2(ログインから情報表示までのSシステムの画面繊維)の注記に「利用者のログイン後、セッションIDでセッション管理を行なっている。セッションIDは、ログイン時に発行される推測困難な値であり、secure属性が付与されたcookieに格納される。」とあります。
 つまり、利用者のログイン時の利用者IDからセッション情報を生成し、その後の通信はセッション情報に基づき、当該セッション情報に紐づく利用者IDからプロジェクトIDを導くことになります。
 セッション情報は推測困難であることから、利用者側で不正な値を設定することは不可能です。

b:PreparedStatement、c:stmt

「8: java.sql.(b) stmt = con.prepareStatement(sql);」
「9: (c).setInt(1,projectId);」
Javaの知識問題です。
 7行目の「String sql = “SELECT 情報番号, 情報名 FROM 情報管理テーブル WHERE プロジェクトID = ?”;」でSQL分を定義していますが、プロジェクトIDを「?」としてプレースホルダを使用しています。
 javaでプレースホルダを使用してSQLを実行する仕組みとしてプリペアドステートメント(prepared statement)があります。
 プリペアドステートメントは、プログラムからデータベースを利用する際、事前に変数を埋め込んだSQLを準備しておき、SQLのバインド変数を利用して、そのSQLを再利用する機能です。
 具体的には、「java.sql.PreparedStatement」というオブジェクトを使います。
 8行目で、「java.sql.PreparedStatement」で「stmt」という名前を宣言し、7行目のsql分を格納します。
 そして、9行目で「projectId」の値を数値型(Int)として割り当てますが、これには「java.sql.PreparedStatement」で宣言した「stmt」が該当します。