サイトアイコン やさしいネットワークとセキュリティ

【情報処理安全確保支援士試験 令和6年度 春期 午後 問4 設問2】徹底解説!Javaセキュアコーディング編

前回に引き続き、令和6年度 春期 情報処理安全確保支援士 午後 問4 の解説をお届けします。今回は、多くの受験者が苦手意識を持つかもしれない、ソースコードの読解が問われる 【設問2】 です。

この設問は、採点講評で「Java言語での例外処理仕様を理解していないと思われる解答が散見された」「セキュアコーディングの基本的内容であり、正確に理解してほしい」 とコメントされている通り、セキュリティのプロフェッショナルとして必須の知識が問われています。

一見難しそうに見えるJavaのコードも、ポイントを押さえれば大丈夫!一緒に脆弱性を見抜く目を養っていきましょう。


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

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

[ユーザー登録機能のセキュリティレビュー]
 ユーザー登録機能は、UserDataクラスによって実現している。UserDataクラスのプログラム仕様を図2に、UserDataクラスのソースコードを図3に示す。


 E氏は、図3のソースコードについて、次のように指摘した。

 E氏の指摘を受け、システム開発者は、UserDataクラスのソースコードを修正した。修正後のUserDataクラスのソースコードを図4に示す。


 図4のソースコードについて、E氏は、セキュリティレビューを再度実施した。
 E氏は、図4のソースコードでは、レインボーテーブル攻撃を受けたときに攻撃が成立してしまうので、図2の仕様及び②図4のソースコードの6、7行目を修正すべきであると指摘した。

 A社は、E氏の指摘の対応を完了した。その後、テストを実施し、Web受注システムをリリースした。

🎯 ユーザー登録機能のセキュリティレビュー

設問2の舞台は、Web受注システムの「ユーザー登録機能」です。セキュリティ専門家のE氏が、ユーザー登録処理を実装したJavaのソースコード(図3)をレビューし、いくつかの問題点を指摘しました。この指摘内容を一つずつ解き明かしていくのが、今回のテーマです。


設問2 (1), (2)

(1) 本文中の (d) に入れる適切な行番号を、図3中から選び、答えよ。
(2) 本文中の (e) に入れる適切な字句を答えよ。

【解説】

この設問は、E氏の以下の指摘に関するものです。 「今後、メンテナンスなどで実行環境を変更した場合に、(d) 行目で (e) が発生すると、25、26行目では、パスワードが平文でユーザーマスターテーブルに保存されてしまう。」

これは非常に深刻な脆弱性ですね。なぜこんなことが起きてしまうのか、図3のソースコードを追ってみましょう。

  1. パスワード処理の流れ
    • まず、3行目でユーザーが入力した平文のパスワードが、インスタンス変数 this.password にセットされます 。
    • 次に、4行目から始まる try ブロックの中で、パスワードのハッシュ化が行われます 。
    • 5行目で MessageDigest.getInstance(“SHA-1”) という処理があります 。これは「SHA-1」という方式でハッシュ化を行う準備です。
    • もし、この5行目で「指定されたハッシュアルゴリズム(SHA-1)が見つからない」という例外(NoSuchAlgorithmException)が発生すると、プログラムの処理は9行目の catch ブロックにジャンプします 。
    • 重要なのは、例外が発生すると、7行目のハッシュ値でパスワードを上書きする処理が実行されないという点です 。
    • catch ブロックでログを出力した後、プログラムはそのまま後続のDB登録処理に進みます。
    • その結果、23行目のDB登録処理では、変数 this.password にはハッシュ化される前の平文パスワードが入ったままとなり、それがデータベースに保存されてしまうのです。

この流れから、脆弱性の原因となる処理と、発生する事象が明らかになりました。

【解答】


設問2 (3)

本文中の下線①について、システム運用担当者とシステム開発者が、アクセスが禁止されているのにアクセスできてしまう情報は何か。図2中のユーザーマスターテーブルの列名で、それぞれ全て答えよ。また、その情報が出力される場所を、解答群の中から選び、それぞれ記号で答えよ。

解答群
ア 開発ログサーバのAPログを保存したテキストファイル
イ 本番APサーバの/sbinディレクトリ配下のバイナリファイル
ウ 本番APサーバの/var/dataディレクトリ配下のCSVファイル
エ 本番APサーバの/var/log/serverlogディレクトリ配下のテキストファイル
オ 本番ログサーバのAPログを保存したテキストファイル

【解説】

下線①の指摘は「システム運用担当者とシステム開発者が、要件でアクセスが禁止されている情報にアクセスできてしまう」 というものです。これは、不適切なログ出力が原因で発生する典型的な情報漏洩の問題です。

1. 何が、どこに出力されているか? 図3のソースコードを見ると、2つのログ出力処理があります。

そして、どちらのログも

this.toString() の内容を出力しています。これは UserData オブジェクトの中身、つまりパスワード、氏名、住所、電話番号、メールアドレスといった重要情報 をそのまま文字列にして出力していると考えられます。

2. 誰が、どこにアクセスできるか? 要件と権限設定を再確認します。

3. 結論

【解答】


設問2 (4)

図4中の (f) に入れる適切な字句を答えよ。

【解説】

この設問は、E氏の「パスワードからハッシュ値を得るためのハッシュ関数が、表1の要件を満たしていない」 という指摘への修正に関するものです。

したがって、(f) には電子政府推奨暗号リストに記載されているハッシュ関数名を入れる必要があります。代表的なものとして、SHA-256SHA-384SHA-512が挙げられます。

【解答】

SHA-256/SHA-384/SHA-512


設問2 (5)

図4中の (g) に入れる適切な処理を、ソースコード又は具体的な処理内容のいずれかで答えよ。

【解説】

これは、設問(1),(2)で明らかになった「例外が発生すると平文パスワードがDB登録されてしまう」問題への対策です。図4のコードでは、

catch (NoSuchAlgorithmException e) ブロックで「回復不能な例外発生」として (g) の処理を求めています

図3の問題は、例外をcatchはするものの、その後の処理を止めずに続行してしまったことでした。 回復不能な例外が発生した場合、処理を安全に中断させるのが鉄則です。

Javaでは、このような場合に RuntimeException をスロー(throw)します。RuntimeException は、プログラムの実行をその場で停止させる効果があり、後続のDB登録処理が実行されるのを防ぐことができます。

【解答】

throw new RuntimeException(e) もしくは ランタイムエラーを例外としてthrowする


設問2 (6)

図4中の (h) に入れる適切なソースコードを答えよ。

【解説】

この設問は、E氏の「変数psObjの指すメモリ領域においてメモリリークが発生する可能性がある」 という指摘への対策です。これは、DB接続などで確保したリソースが、プログラム終了後も解放されない問題です。

図3では、DB操作を行うための PreparedStatement オブジェクトを生成していますが、try ブロック内で例外が発生した場合に、このオブジェクトを閉じる(closeする)処理が実行されない可能性がありました。

図4では、この問題を解決するために、DB処理を

try-catch ブロックで囲み、その後に (h) ブロックを設けてリソースのクローズ処理を記述しています

プログラムの正常終了時でも、例外発生時でも、どんな状況でも必ず実行したい処理を記述するための構文。それが finally 句です。finally ブロックにリソースのクローズ処理を記述するのが、Javaにおけるリソースリーク対策の定石です。

【解答】

finally


設問2 (7)

本文中の下線②について、図4の6、7行目をどのように修正すればよいか。修正後の適切なソースコードを解答群の中から選び、記号で答えよ。ここで、変数 saltには、addUserメソッドの呼出しごとに異なる32バイトの固定長文字列が入っているものとするし、ユーザーマスターテーブルの定義に変更はないものとする。

【解説】

最後の問題です!下線②の指摘は「レインボーテーブル攻撃を受けたときに攻撃が成立してしまう」 というものです。

ソルトを利用したパスワード保存のポイントは2つです。

  1. 保存時: 「ソルト + パスワード」をハッシュ化する。
  2. DBへの格納: 次回の認証時に同じソルトを使えるように、生成したソルトハッシュ値の両方をDBに保存する必要がある。

このポイントを踏まえて解答群を見ていきましょう。

したがって、ソルトを正しく利用してレインボーテーブル攻撃対策ができているのは、選択肢アです。

【解答】

まとめ

設問2、お疲れ様でした!Javaのコードが出てきて戸惑った方もいるかもしれませんが、問われているのはセキュアコーディングの基本的な考え方です。

これらの原則は、言語が変わっても通用する普遍的なものです。今回の問題を通して、ぜひセキュアコーディングの「勘所」を身につけてくださいね!

モバイルバージョンを終了