情報処理安全確保支援士 2024年 春期 午後 問04
Webアプリケーションプログラムに関する次の記述を読んで、設問に答えよ。
A社は、加工食品の製造・販売を行う従業員500名の会社である。問屋や直販店からの注文の受付に、商品の注文と在庫を管理するシステム(以下、業務システムという)を利用している。業務システムは、A社内に設置したサーバ上に構築されている。
このたび、販売拡大を目指して、インターネットを使ったギフト販売を行うことになり、個人顧客から注文を受けるためのWebシステム(以下、Web受注システムという)を構築することになった。
A社はITベンダーのB社との間で開発の委託契約を締結し、両社はWeb受注システムの開発に着手した。
〔Web受注システムの要件〕
Web受注システムの要件を表1に示す。


〔Web受注システムの設計〕
A社とB社はWeb受注システムを設計した。
Web受注システムのサーバで定義されるOSアカウントの一覧を表2に、所属グループとその権限を表3に示す。


業務システムとWeb受注システムは、CSV形式のデータ連携用ファイル(以下、CSVファイルという)でデータ連携を行う。1時間ごとに業務システムのバッチサーバとWeb受注システムのバッチサーバにおいてCSVファイルを作成し、HTTPSで他方のバッチサーバに送信し、他方のバッチサーバでは受信したCSVファイルを保存する。保存したCSVファイルを使用してWeb受注システム又は業務システムのDBに対して更新処理を実行する。更新処理後のCSVファイルは、障害発生に備えて1週間保存する。
データ連携機能のプログラム一覧を表4に示す。

表4のうち、No.3のプログラムの内容を図1に示す。

Web受注システムの開発が進み、結合テスト前に、A社は、設計書とソースコードのセキュリティレビューを、セキュリティ専門会社の C社に委託した。C社の情報処理安全確保支援士(登録セキスペ)の E 氏は、セキュリティレビューを実施した。
〔データ連携機能のセキュリティレビュー〕
E氏は、表2~4 及び図1の内容では表1の要件を満たしておらず、aがCSV ファイルを閲覧できてしまうという問題を発見した。また、CSV ファイルには重要情報が記録されるので、本番バッチサーバにアクセスできる者が不正に閲覧するリスクを軽減するための保険的対策も併せて実施することを提案した。具体的には、次のように提案した。
(1) 問題に対しては、表2のbatchappuser について、所属グループをbに変更する。
(2) 保険的対策としては、表4のNo.3 のプログラムに暗号化を行う処理を追加し、表4のNo.c のプログラムに復号を行う処理を追加する。
A社は、E 氏の提案どおり修正することにした。
〔ユーザー登録機能のセキュリティレビュー〕
ユーザー登録機能は、UserDataクラスによって実現している。UserDataクラスのプログラム仕様を図2に、UserDataクラスのソースコードを図3に示す。


E氏は、図3のソースコードについて、次のように指摘した。
・パスワードからハッシュ値を得るためのハッシュ関数が、表1の要件を満たしていない。
・今後、メンテナンスなどで実行環境を変更した場合に、d行目でeが発生すると、25、26行目では、パスワードが平文でユーザーマスタテーブルに保存されてしまう。
・①システム運用担当者とシステム開発者が、要件でアクセスが禁止されている情報にアクセスできてしまう。
・利用するAPサーバの実装では、変数psObjの指すメモリ領域においてメモリリークが発生する可能性がある。
E氏の指摘を受け、システム開発者は、UserDataクラスのソースコードを修正した。
修正後のUserDataクラスのソースコードを図4に示す。


図4のソースコードについて、E氏は、セキュリティレビューを再度実施した。
E氏は、図4のソースコードでは、レインボーテーブル攻撃を受けたときに攻撃が成立してしまうので、図2の仕様及び②図4のソースコードの6, 7行目を修正すべきであると指摘した。
A社は、E氏の指摘の対応を完了した。その後、テストを実施し、Web受注システムをリリースした。
設問1:〔データ連携機能のセキュリティレビュー〕について答えよ。
(1)本文中のaに入れる適切な字句を、解答群の中から選び、記号で答えよ。
解答群
ア:システム運用担当者
イ:システム運用担当者とシステム開発者
ウ:システム開発者
エ:システム開発者と重要情報取扱運用者
オ:重要情報取扱運用者
模範解答
a:ア
解説
解答の論理構成
-
CSVファイルの格納場所・パーミッションの確認
【問題文】図1では「/var/dataディレクトリのオーナーはbatchappuserで、パーミッションは770」「CSVファイルのオーナーはbatchappuserで、パーミッションは660」と定義されています。
770/660 はいずれも“グループ”にも読み取り権を与える設定です。 -
batchappuser の所属グループを確認
【問題文】表2「batchappuser」の「所属グループ」は「operation」です。 -
“operation” グループに含まれる利用者を確認
【問題文】表2「operator」は「所属グループ operation」で、「説明」に「システム運用担当者が利用する。」と記載されています。
つまり「operation グループ = システム運用担当者が属するグループ」です。 -
CSV ファイル閲覧が可能な人物を導出
① ディレクトリも CSV ファイルもグループに読み取り権がある(770/660)。
② そのグループは“operation”。
③ “operation”に属するアカウントは「operator」=「システム運用担当者」。
よって「システム運用担当者」が CSV ファイルを閲覧できてしまう問題が発生します。 -
解答選択
解答群のうち「システム運用担当者」に該当するのは「ア」。
したがって a には「ア:システム運用担当者」が入ります。
誤りやすいポイント
- 「本番環境へのアクセス権がある」だけではファイルを読めるとは限らない点を見落としやすい。パーミッション(770/660)の具体的設定とグループ名の一致確認が必要です。
- 「重要情報取扱運用者」も本番環境にアクセスできるため誤答しやすいが、当該ディレクトリのグループが personal ではなく operation である点が決定的です。
- 「システム開発者」は本番ログサーバのみアクセス可(表3)で、本番バッチサーバにはアクセス権がないことを忘れがちです。
FAQ
Q: 770 と 660 の違いは何を意味しますか?
A: 770 はディレクトリに対して「所有者 rwx/グループ rwx/その他 なし」、660 はファイルに対して「所有者 rw/グループ rw/その他 なし」を示します。いずれもグループに読み取り権を与えています。
A: 770 はディレクトリに対して「所有者 rwx/グループ rwx/その他 なし」、660 はファイルに対して「所有者 rw/グループ rw/その他 なし」を示します。いずれもグループに読み取り権を与えています。
Q: 「personal」グループのユーザーは CSV を閲覧できますか?
A: パーミッション上は閲覧不可です。ディレクトリ・ファイルのグループが「operation」なので、「personal」グループのメンバーは権限を持ちません。
A: パーミッション上は閲覧不可です。ディレクトリ・ファイルのグループが「operation」なので、「personal」グループのメンバーは権限を持ちません。
Q: batchappuser を personal グループに変更すると何が変わりますか?
A: ディレクトリ・ファイルのグループが personal になり、重要情報の取り扱いが許可されている「重要情報取扱運用者」のみが閲覧可能となり、システム運用担当者からの不正閲覧リスクを低減できます。
A: ディレクトリ・ファイルのグループが personal になり、重要情報の取り扱いが許可されている「重要情報取扱運用者」のみが閲覧可能となり、システム運用担当者からの不正閲覧リスクを低減できます。
関連キーワード: アクセス権, Linuxパーミッション, グループ管理, 情報漏えいリスク
設問1:〔データ連携機能のセキュリティレビュー〕について答えよ。
(2)本文中のbに入れる適切な所属グループを、表3中から選び答えよ。
模範解答
b:personal
解説
解答の論理構成
- CSV ファイルが置かれる /var/data ディレクトリは「パーミッションは770」と設計されています。
770 は なので、 • 所有者 batchappuser … 読み書き実行可
• 所属グループ … 読み書き実行可
• その他 … 権限なし - 表2より、初期状態で batchappuser の「所属グループ」は operation です。
「batchappuser」「operation」「本番バッチサーバ」
- 表3より operation グループには
「本番 AP サーバと本番バッチサーバへのアクセス権がある」
と定義されており、一般ユーザー権限ながら本番バッチサーバへログインできます。 - 役割定義(表1-18)ではシステム運用担当者について
「重要情報にアクセスしてはならない。」
とあり、operation グループはまさにそのシステム運用担当者が利用する OS アカウント operator の所属先です。 - よって batchappuser が operation グループのままだと、 「システム運用担当者が /var/data の CSV ファイルを閲覧できてしまう」問題が発生します。
- 重要情報を扱う権限があるのは表1-18(3) 重要情報取扱運用者 であり、その OS アカウント personal の所属先は personal グループです。表3では
「personal」「一般ユーザー権限である。本番環境へのアクセス権がある。」
と記載されています。 - したがって batchappuser の所属グループを personal に変更すれば、
• システム運用担当者(operation)からのアクセス不可
• 重要情報取扱運用者(personal)のみアクセス可能
となり、要件を満たせます。 - 以上より b に入る適切な所属グループは personal です。
誤りやすいポイント
- 「operation グループは監視だけだから読み取り権限は不要」という前提を見落とし、パーミッション 770 の意味を深掘りせずに root なら OK と考えてしまう。
- 「develop グループもログサーバへ入れる=develop で良いのでは」と誤認し、CSV 連携先がバッチサーバであることを忘れる。
- 770 を 750 と読み間違え、「グループは読み取り不可」と勘違いする。
FAQ
Q: グループを personal に変える代わりにディレクトリを 700 にする方法は?
A: batchappuser が実行するプログラム以外が CSV を読む正当な場面もあるため、一律 700 では運用に支障が出る可能性があります。グループ管理の方が権限と役割を対応させやすいという判断です。
A: batchappuser が実行するプログラム以外が CSV を読む正当な場面もあるため、一律 700 では運用に支障が出る可能性があります。グループ管理の方が権限と役割を対応させやすいという判断です。
Q: 新たに「csvgroup」のような専用グループを作らないのは?
A: 役割ベースアクセス制御を簡素に保つため、既存の「重要情報取扱運用者」と同じグループ personal に集約した方が管理負荷が低く、試験要件内で十分と判断されました。
A: 役割ベースアクセス制御を簡素に保つため、既存の「重要情報取扱運用者」と同じグループ personal に集約した方が管理負荷が低く、試験要件内で十分と判断されました。
Q: personal グループに属するのは重要情報取扱運用者だけですか?
A: OS アカウント一覧(表2)では personal グループに属するのは「personal」と今回変更する「batchappuser」のみです。想定上、どちらも重要情報を扱う正当な権限を持ちます。
A: OS アカウント一覧(表2)では personal グループに属するのは「personal」と今回変更する「batchappuser」のみです。想定上、どちらも重要情報を扱う正当な権限を持ちます。
関連キーワード: アクセス権、所属グループ、パーミッション、役割分担、CSVファイル
設問1:〔データ連携機能のセキュリティレビュー〕について答えよ。
(3)本文中のcに入れる適切なプログラムを、表4中から選び、No.列の番号で答えよ。
模範解答
c:4
解説
解答の論理構成
- 暗号化が施される箇所を確認
- 問題文に「表4のNo.3 のプログラムに暗号化を行う処理を追加し」とあります。
- 表4 No.3 は「注文データCSV出力バッチ処理」であり、Web受注システム側でCSVファイルを作成する処理です。
- 復号が必要になるタイミングを整理
- 暗号化されたCSVはHTTPSで業務システム側へ送られます(No.7「データ送信1バッチ処理」→No.10「データ受信2バッチ処理」)。
- 受信後にCSVの内容をDBへ反映するのは表4 No.4「注文データCSV取り込みバッチ処理」です。
- 復号を実装すべきプログラムを決定
- 復号は「保存されたCSVファイルを読み込んで、業務システムのDBを更新する」処理の直前または処理内で行うのが最も自然です。
- したがって、暗号化ファイルを読み取るNo.4に復号ロジックを追加することで整合が取れ、要件「CSV ファイルには重要情報が記録されるので…リスクを軽減」に合致します。
- 結論
- c に入るのは表4「注文データCSV取り込みバッチ処理」の番号、すなわち「4」です。
誤りやすいポイント
- 「データ受信2バッチ処理(No.10)」と混同する
- No.10はファイルを“保存”するのみでDB操作を行わないため、復号をここで行うと保存用ディレクトリに平文が残ってしまいます。
- 「データ送信1バッチ処理(No.7)」を選んでしまう
- No.7は送信側であり、暗号化と同じWeb受注システム側なので復号の対象外です。
- CSV出力・取込み双方で暗号化/復号を誤配置すると、後続処理がファイルを読めず障害が発生します。
FAQ
Q: 復号をNo.10「データ受信2バッチ処理」で行うのは駄目でしょうか?
A: 保存専用ディレクトリに平文が置かれるためリスク軽減になりません。DB更新直前のNo.4で復号する方が適切です。
A: 保存専用ディレクトリに平文が置かれるためリスク軽減になりません。DB更新直前のNo.4で復号する方が適切です。
Q: 両システム間の通信はHTTPSなので暗号化は不要では?
A: HTTPSは転送経路の保護です。E氏の提案は「本番バッチサーバにアクセスできる者が不正に閲覧するリスク」を低減する保険的対策であり、保管時暗号も必要です。
A: HTTPSは転送経路の保護です。E氏の提案は「本番バッチサーバにアクセスできる者が不正に閲覧するリスク」を低減する保険的対策であり、保管時暗号も必要です。
Q: 暗号・復号の鍵管理はどこで行いますか?
A: 鍵はシステム管理責任者が管理し、本番APサーバ/本番バッチサーバ上の安全なキーストアに格納する想定です。
A: 鍵はシステム管理責任者が管理し、本番APサーバ/本番バッチサーバ上の安全なキーストアに格納する想定です。
関連キーワード: CSV暗号化, 復号処理, バッチ連携, アクセス制御, 保管時暗号
設問2:〔ユーザー登録機能のセキュリティレビュー〕について答えよ。
(1)本文中のdに入れる適切な行番号を、図3中から選び、答えよ。
模範解答
d:5
解説
解答の論理構成
- 図3の該当箇所を確認します。
- 5: MessageDigest mdObj = MessageDigest.getInstance("SHA-1");
- 6: byte[] hashByte = mdObj.digest(this.password.getBytes());
- ハッシュ関数オブジェクトの生成に失敗すると NoSuchAlgorithmException が送出されます。
【問題文】
“今後、メンテナンスなどで実行環境を変更した場合に、d行目でeが発生すると、25、26行目では、パスワードが平文でユーザーマスタテーブルに保存されてしまう。” - ハッシュ化前に唯一例外が発生し得るのは行5の MessageDigest.getInstance("SHA-1") であり、ここで例外が発生すると行6以降のハッシュ処理は実行されません。
- 例外捕捉後も this.password には平文が残るため、そのまま
- 21: psObj.setString(3, this.password);
で DB へ保存されることになります。
- 21: psObj.setString(3, this.password);
- したがって d に入る行番号は “5” です。
誤りやすいポイント
- 行6で例外が発生すると考えてしまう。実際には行6は mdObj が null でなければ実行され、例外は原則発生しません。
- catch 節でログは出しているので安全と誤認し、平文保存リスクを見落とす。
- “ハッシュ化に失敗したら登録処理自体が止まる” と想定し、その後の処理を追跡しない。
FAQ
Q: 例外発生時に登録処理全体をロールバックすれば平文保存の問題は解消しますか?
A: はい。ただし設計上は「ハッシュ化に失敗したら登録自体を中断する」方が安全であり、本来は例外再送出やバリデーションエラーとして扱うべきです。
A: はい。ただし設計上は「ハッシュ化に失敗したら登録自体を中断する」方が安全であり、本来は例外再送出やバリデーションエラーとして扱うべきです。
Q: ハッシュ関数生成失敗は実運用で起こり得ますか?
A: アルゴリズム名の変更や Java ランタイム差し替え時に除外される可能性があり、ゼロとは言えません。保険的対策としても例外時に処理を停止してログを残す設計が推奨されます。
A: アルゴリズム名の変更や Java ランタイム差し替え時に除外される可能性があり、ゼロとは言えません。保険的対策としても例外時に処理を停止してログを残す設計が推奨されます。
Q: String.format("%x"、…) でハッシュ値を 16 進文字列化していますが、セキュリティ上問題ありませんか?
A: 文字列表現自体に問題はありません。ただしレインボーテーブル攻撃対策としてソルト付与やストレッチングを併用する必要があります。
A: 文字列表現自体に問題はありません。ただしレインボーテーブル攻撃対策としてソルト付与やストレッチングを併用する必要があります。
関連キーワード: ハッシュ関数、NoSuchAlgorithmException, 例外処理、平文保存、メッセージダイジェスト
設問2:〔ユーザー登録機能のセキュリティレビュー〕について答えよ。
(2)本文中のeに入れる適切な字句を答えよ。
模範解答
e:例外
解説
解答の論理構成
- 問題文には「今後、メンテナンスなどで実行環境を変更した場合に、d行目でeが発生すると、25、26行目では、パスワードが平文でユーザーマスタテーブルに保存されてしまう。」とあります。
- 図3のソースコードを確認すると、d行目に該当するのは
5: MessageDigest mdObj = MessageDigest.getInstance("SHA-1");
であり、この行で想定される障害は MessageDigest.getInstance() がアルゴリズムを見つけられない場合に送出される NoSuchAlgorithmException です。 - NoSuchAlgorithmException は Java における checked 例外であり、catch 句側にも catch (NoSuchAlgorithmException e) と明示されています。
- よって、e には「例外」が入るのが論理的に整合します。
誤りやすいポイント
- Error と混同する:Java の Error と Exception は別物。ここで問題にしているのは checked 例外です。
- 例外名をそのまま書く:設問は字句を尋ねており、「NoSuchAlgorithmException」ではなく汎用語「例外」を要求しています。
- try-catch 全体ではなく個別行に着目し忘れる:質問は “d行目で発生するもの” を指しているため、行単位の原因と結果を正確に追う必要があります。
FAQ
Q: 具体的な例外名(NoSuchAlgorithmException)ではなく「例外」と答える理由は?
A: 設問は “e が発生すると” と抽象的に述べており、個別クラス名ではなく一般名詞で答えさせる形式だからです。
A: 設問は “e が発生すると” と抽象的に述べており、個別クラス名ではなく一般名詞で答えさせる形式だからです。
Q: NoSuchAlgorithmException は実環境の変更でなぜ発生しやすいのですか?
A: Java ランタイムから該当アルゴリズムが除外・無効化される構成変更を行うと、MessageDigest.getInstance() がアルゴリズムを解決できず例外が送出されます。
A: Java ランタイムから該当アルゴリズムが除外・無効化される構成変更を行うと、MessageDigest.getInstance() がアルゴリズムを解決できず例外が送出されます。
Q: 例外が発生すると平文保存になるのはなぜ?
A: catch 句ではハッシュ化失敗時に this.password を更新しないまま後続処理に進むため、3行目で取得した平文文字列が 25,26 行目でそのまま INSERT されてしまうからです。
A: catch 句ではハッシュ化失敗時に this.password を更新しないまま後続処理に進むため、3行目で取得した平文文字列が 25,26 行目でそのまま INSERT されてしまうからです。
関連キーワード: ハッシュ関数、NoSuchAlgorithmException, 例外処理、平文パスワード
設問2:〔ユーザー登録機能のセキュリティレビュー〕について答えよ。
(3)本文中の下線①について、システム運用担当者とシステム開発者が、アクセスが禁止されているのにアクセスできてしまう情報は何か。図2中のユーザマスターテーブルの列名で、それぞれ全て答えよ。また、その情報が出力される場所を、解答群の中から選び、それぞれ記号で答えよ。
(「システム運用担当者」は、不備により設問が成立しないため採点対象外)
解答群
ア:開発ログサーバのAPログを保存したテキストファイル
イ:本番APサーバの/sbinディレクトリ配下のバイナリファイル
ウ:本番APサーバの/var/dataディレクトリ配下のCSVファイル
エ:本番APサーバの/var/log/serverlogディレクトリ配下のテキストファイル
オ:本番ログサーバのAPログを保存したテキストファイル
模範解答
システム運用担当者:
アクセスできてしまう情報:不備により設問が成立しないため採点対象外
出力される場所:不備により設問が成立しないため採点対象外
システム開発者パスワード:
アクセスできてしまう情報:パスワード、氏名、住所、電話番号、メールアドレス
出力される場所:オ
解説
解答の論理構成
-
【問題文】表1の「重要情報(注1)に該当するデータ項目」には
“氏名、住所、電話番号、メールアドレス、パスワード”
が列挙されています。 -
図3の22~25行目ではSystem.out.println("InsertData:" + this.toString()); log.debug("InsertData:" + this.toString());として、this.toString() が保持するインスタンス変数(図2参照)をそのまま出力しています。したがって上記5項目の値がログに記録されます。
-
表3で “develop” グループは
“一般ユーザー権限である。開発環境と本番ログサーバへのアクセス権がある。”
と規定されており、システム開発者(ユーザーID “developer”)は本番ログサーバを閲覧できます。 -
解答群「オ」は “本番ログサーバのAPログを保存したテキストファイル” なので、システム開発者が閲覧できてしまう場所に該当します。
-
以上より、アクセスされてしまう情報は
“パスワード、氏名、住所、電話番号、メールアドレス”
であり、出力先は解答群「オ」です。
誤りやすいポイント
- CSV ファイル(解答群「ウ」)を選んでしまう
→ CSV 出力はバッチサーバ上にあり、システム開発者(“developer”)はアクセス権がない。 - “ユーザーOID” や “ユーザーID” を含めてしまう
→ 下線①の指摘は「要件でアクセスが禁止されている情報」=表1の重要情報のみが対象。 - ログ出力箇所を System.out.println() だけと判断
→ log.debug() も本番ログサーバへ転送される点を見落としやすい。
FAQ
Q: なぜ本番APサーバの /var/log/serverlog(解答群「エ」)ではないのですか?
A: “develop” グループにそのディレクトリへのアクセス権は与えられていません。表3の権限定義を確認してください。
A: “develop” グループにそのディレクトリへのアクセス権は与えられていません。表3の権限定義を確認してください。
Q: “パスワード” 以外の4項目も漏れる根拠は?
A: this.toString() が図2の全インスタンス変数(氏名等)を連結しているためです。
A: this.toString() が図2の全インスタンス変数(氏名等)を連結しているためです。
Q: システム運用担当者が採点対象外とあるのは?
A: 問題文に「(不備により設問が成立しないため採点対象外)」と明記されています。
A: 問題文に「(不備により設問が成立しないため採点対象外)」と明記されています。
関連キーワード: デバッグログ、アクセス制御、重要情報、権限定義、ログ管理
設問2:〔ユーザー登録機能のセキュリティレビュー〕について答えよ。
(4)図4中のfに入れる適切な字句を答えよ。
模範解答
f:・SHA-256
・SHA-384
・SHA-512
解説
解答の論理構成
- 要件確認
【問題文】表1 No.19 には
「パスワードは、CRYPTREC暗号リスト(令和5年3月30日版)の電子政府推奨暗号リストに記載されているハッシュ関数でハッシュ化してDBに保存する。」
と明記されています。 - 現状の問題点
図3の旧コード 5 行目は
MessageDigest mdObj = MessageDigest.getInstance("SHA-1");
としており、「SHA-1」は電子政府推奨暗号リストから除外されています。 - 採用すべきハッシュ関数
同リストでパスワードハッシュ用途に利用できる代表的な関数は
「SHA-256」「SHA-384」「SHA-512」です。 - コード修正箇所
図4 5 行目の f には、上記いずれかを指定すれば要件を満たします。
誤りやすいポイント
- 「SHA-1 も Secure Hash だから可」と早合点してしまう。推奨リストにないため失格です。
- MD5 や RIPEMD-160 を選ぶ。どちらも現行リストには載っていません。
- bcrypt など派生アルゴリズムを直接指定しようとする。Java 標準 MessageDigest では扱えず問題の前提外です。
FAQ
Q: 3 種類のうちどれを選んでも得点は同じですか?
A: はい。設問は「適切な字句」を求めており、いずれも要件を満たすため正解です。
A: はい。設問は「適切な字句」を求めており、いずれも要件を満たすため正解です。
Q: MessageDigest で SHA3-256 は使えますか?
A: 実装によっては可能ですが、電子政府推奨暗号リスト(令和5年3月30日版)に未掲載のため本設問では不適切です。
A: 実装によっては可能ですが、電子政府推奨暗号リスト(令和5年3月30日版)に未掲載のため本設問では不適切です。
Q: ハッシュだけで十分ですか?ソルトは不要ですか?
A: 後段でレインボーテーブル対策としてソルト追加の指摘があります。ハッシュアルゴリズム選択とソルト付与は別の防御層です。
A: 後段でレインボーテーブル対策としてソルト追加の指摘があります。ハッシュアルゴリズム選択とソルト付与は別の防御層です。
関連キーワード: 電子政府推奨暗号リスト、SHA-256, ハッシュ関数、パスワードハッシュ、MessageDigest
設問2:〔ユーザー登録機能のセキュリティレビュー〕について答えよ。
(5)図4中のgに入れる適切な処理を、ソースコード又は具体的な内容のいずれかで答えよ。
模範解答
g:・thrownewRuntimeException(e)
・ランタイムエラーを例外としてthrowする。
解説
解答の論理構成
- 【問題文】には、初版ソースコードに対する指摘として
“今後、メンテナンスなどで実行環境を変更した場合に、d行目でeが発生すると、25、26行目では、パスワードが平文でユーザーマスタテーブルに保存されてしまう。”
とあり、例外発生後に処理を継続すると平文保存の危険があると明示されています。 - 修正後コード(図4)の 8~10 行目には
8: log.debug("error:" + e);
//回復不能な例外発生
10: g;
とコメントされ、“回復不能”であるため処理を中断する必要があることが示唆されています。
3. Java で回復不能な例外を上位に通知して処理を停止させる一般的な方法は、RuntimeException などの unchecked 例外を送出(throw)することです。これにより以降の INSERT 処理(25 行目以降)は実行されず、平文のまま DB へ保存される事態を防げます。
4. 以上より、g には “例外をそのままラップして再スローする” 処理、すなわち
throw new RuntimeException(e);
を記述するのが最適解となります。
3. Java で回復不能な例外を上位に通知して処理を停止させる一般的な方法は、RuntimeException などの unchecked 例外を送出(throw)することです。これにより以降の INSERT 処理(25 行目以降)は実行されず、平文のまま DB へ保存される事態を防げます。
4. 以上より、g には “例外をそのままラップして再スローする” 処理、すなわち
throw new RuntimeException(e);
を記述するのが最適解となります。
誤りやすいポイント
- return; でメソッドを終了させるだけでは呼び出し側が異常を検知できず、上位層でコミット処理が行われる危険があります。
- System.exit() でプロセスを終了させると AP サーバ全体が停止し、可用性要件 “稼働率目標 99.9%” を損なう恐れがあります。
- SQLException など別の例外型で投げ直すと、呼び出し階層でキャッチ漏れが起きる可能性があります。ハッシュ関数取得失敗は DB とは無関係なため、汎用的な RuntimeException を用いるのが妥当です。
FAQ
Q: 例外を throws NoSuchAlgorithmException として宣言し、呼び出し側で捕捉する方法ではダメですか?
A: 本メソッドはコンストラクタであり、チェック例外を投げると呼び出し箇所すべてで例外処理が必須になります。実装負荷や既存コードとの整合を考慮し、unchecked 例外で上位に通知する方が現実的です。
A: 本メソッドはコンストラクタであり、チェック例外を投げると呼び出し箇所すべてで例外処理が必須になります。実装負荷や既存コードとの整合を考慮し、unchecked 例外で上位に通知する方が現実的です。
Q: RuntimeException 以外に推奨される例外型はありますか?
A: Java 8 以降であれば IllegalStateException や UnsupportedOperationException も候補ですが、実装依存が少なく汎用性の高い RuntimeException が一般的です。
A: Java 8 以降であれば IllegalStateException や UnsupportedOperationException も候補ですが、実装依存が少なく汎用性の高い RuntimeException が一般的です。
Q: 例外送出後にログは残さなくてよいのでしょうか?
A: 8 行目の log.debug("error:" + e); でエラー内容は既に記録されます。これにより障害解析用の情報が確保され、追加のログは必須ではありません。
A: 8 行目の log.debug("error:" + e); でエラー内容は既に記録されます。これにより障害解析用の情報が確保され、追加のログは必須ではありません。
関連キーワード: 例外処理、RuntimeException, ハッシュ関数、パスワードハッシュ
設問2:〔ユーザー登録機能のセキュリティレビュー〕について答えよ。
(6)図4中のhに入れる適切なソースコードを答えよ。
模範解答
h:finally
解説
解答の論理構成
- 図4では
17:try { … }
27:} catch (SQLException e) { … }
28:} h {
という構造になっています。この形は Java の例外処理三部構成「try‐catch‐finally」を示唆します。 - 23~24行目でログ出力、25~26行目で psObj.execute() と conn.commit() を行った後、33行目で psObj.close() を実行しリソースを確実に解放する意図が読み取れます。リソース解放は例外発生の有無にかかわらず実行する必要があるため、finally 節に置くのが適切です。
- 問題文には「利用するAPサーバの実装では、変数psObjの指すメモリ領域においてメモリリークが発生する可能性がある。」とあります。メモリリーク防止には finally で close を呼び出すのが王道であり、これも finally 選択を裏付けています。
- 以上より、h に入るキーワードは Java 構文の finally となります。
誤りやすいポイント
- try ブロック内で commit() に成功した場合だけ close すれば十分だと誤解し、finally ではなく catch 内に close を書いてしまう。
- Java7 以降の try-with-resources を連想して別解を探した結果、設問のコード構造(Java6 相当)と整合しない回答を書く。
- 例外発生時にロールバックを行うべきかどうかに気を取られ、設問が求めるキーワードを見落とす。
FAQ
Q: catch のすぐ後に finally を書くと、catch が処理を投げた例外も握りつぶされない?
A: finally 節は例外の発生有無に関係なく最後に必ず実行され、catch で処理した例外の挙動を変えることはありません。
A: finally 節は例外の発生有無に関係なく最後に必ず実行され、catch で処理した例外の挙動を変えることはありません。
Q: try-with-resources ではだめなのですか?
A: もちろん最新 Java では推奨ですが、図4のソースは従来構文で記載されており、設問もその文脈で問われています。
A: もちろん最新 Java では推奨ですが、図4のソースは従来構文で記載されており、設問もその文脈で問われています。
Q: finally 節で close() が再び SQLException を投げたらどうなりますか?
A: 図4では内部で再度 try-catch を用いて close() 例外を捕捉しているため、外側への影響は抑えられます。
A: 図4では内部で再度 try-catch を用いて close() 例外を捕捉しているため、外側への影響は抑えられます。
関連キーワード: 例外処理、リソース解放、メモリリーク、PreparedStatement, ハッシュ関数
設問2:〔ユーザー登録機能のセキュリティレビュー〕について答えよ。
(7)本文中の下線②について、図4の6、7行目をどのように修正すればよいか。修正後の適切なソースコードを解答群の中から選び、記号で答えよ。ここで、変数saltには、addUserメソッドの呼出しごとに異なる32バイトの固定長文字列が入っているものとし、ユーザーマスターテーブルの定義に変更はないものとする。


模範解答
ア
解説
解答の論理構成
- 図4の現行コードは
6 行目 byte[] hashByte = mdObj.digest(this.password.getBytes());
7 行目 this.password = String.format("%x"、new BigInteger(1, hashByte));
となっており、入力パスワードをそのままハッシュ化してデータベースに保存します。 - 本文には「レインボーテーブル攻撃を受けたときに攻撃が成立してしまう」とあります。レインボーテーブルは“あらかじめ計算されたハッシュ値一覧”を用いる攻撃なので、パスワードに“salt”を付与してからハッシュ化し、かつ salt を保存しておくことで対策できます。
- 設問の前提は「変数saltには、addUserメソッドの呼出しごとに異なる32バイトの固定長文字列が入っている」。したがって
① salt + password を入力にしてハッシュ化
② ハッシュ結果と salt の両方を列「パスワード」に保存
が必須条件です。 - 解答群を照合すると
ア : hashByte = mdObj.digest((salt + this.password).getBytes());
this.password = salt + String.format("%x"、new BigInteger(1, hashByte));
は条件①②をいずれも満たします。
イ・ウ・エ・オは salt を保存しない、あるいは salt をハッシュに含めていない、二重ハッシュなど要件外の動作を行うため不適切です。 - よって適切な修正はアとなります。
誤りやすいポイント
- salt をハッシュ後に連結する(エ)のような実装ではレインボーテーブル攻撃を防げません。salt は必ずハッシュの入力に含める必要があります。
- salt を保存し忘れる(イ)は検証時に salt が取り出せず、ログイン判定ができなくなります。
- 二重ハッシュや salt のハッシュ化(ウ・オ)は要件外の複雑化につながり、将来の保守で不整合を招きやすくなります。
- “ユニークな salt を生成”と“salt とハッシュを併せて保存”という二段階を混同しがちです。
FAQ
Q: salt を「パスワード」列に連結して保存しても検索は大丈夫ですか?
A: 検索時は入力パスワードに同じ salt を連結してハッシュ化し、保存値と比較するため問題ありません。
A: 検索時は入力パスワードに同じ salt を連結してハッシュ化し、保存値と比較するため問題ありません。
Q: salt を別カラムに分けて保存しても良いですか?
A: 可能ですが、今回のシステムは列定義を変更しない前提なので同一列に先頭連結する方法を選択しています。
A: 可能ですが、今回のシステムは列定義を変更しない前提なので同一列に先頭連結する方法を選択しています。
Q: なぜ「salt + password」の順で連結するのですか?
A: どちらの順でもハッシュ自体の強度は変わりませんが、実装を固定しておくことで検証時に同一手順を再現しやすくなります。今回は先頭連結を採用しています。
A: どちらの順でもハッシュ自体の強度は変わりませんが、実装を固定しておくことで検証時に同一手順を再現しやすくなります。今回は先頭連結を採用しています。
関連キーワード: ソルト、レインボーテーブル攻撃、ハッシュ関数、認証、メッセージダイジェスト


