戦国IT - 情報処理技術者試験の過去問対策サイト
お知らせお問い合わせ料金プラン

情報処理安全確保支援士 2023年 春期 午後101


Webアプリケーションプログラム開発に関する次の記述を読んで、設問に答えよ。

   G社は、システム開発を行う従業員100名のSI企業である。このたび、オフィス用品を販売する従業員200名のY社から、システム開発を受託した。開発プロジェクトのリーダーには、G社の開発課のD主任が任命され、メンバーには、開発課から、Eさんと新人のFさんが任命された。G社では、セキュリティの品質を担保するために、プログラミング完了後にツールによるソースコードの静的解析を実施することにしている。   〔受託したシステムの概要〕  受託したシステムには、Y社の得意先がオフィス用品を注文する機能、Y社とY社の得意先が注文履歴を表示させる機能、Y社とY社の得意先が注文番号を基に注文情報を照会する機能(以下、注文情報照会機能という)、Y社とY社の得意先が納品書のPDFファイルをダウンロードする機能などがある。   〔ツールによるソースコードの静的解析〕  プログラミングが完了し、ツールによるソースコードの静的解析を実施したところ、Fさんが作成した納品書PDFダウロードクラスのソースコードに問題があることが分かった。納品書PDFダウンロードクラスのソースコードを図1に、静的解析の結果を表1に示す。
情報処理安全確保支援士試験(令和5年度 午後1 問01 図01-01)
情報処理安全確保支援士試験(令和5年度 午後1 問01 図01-02)
情報処理安全確保支援士試験(令和5年度 午後1 問01 表01)
 この解析結果を受けて、Fさんは、Eさんの指導の下、ソースコードを修正した。表1の項番1について図1の8行目から11行目を図2に示すソースコードに修正した。項番2と項番3についてもソースコードを修正した。
情報処理安全確保支援士試験(令和5年度 午後1 問01 図02)
 再度、ツールによるソースコードの静的解析が実施され、表1の指摘は解消していることが確認された。   〔システムテスト〕  システムテストを開始したところ、注文情報照会機能において不具合が見つかった。この不具合は、ある得意先の利用者IDでログインして画面から注文番号を入力すると、別の得意先の注文情報が出力されるというものであった。なお、ログイン処理時に、ログインした利用者IDと、利用者IDにひも付く得意先コード及び得意先名はセッションオブジェクトに保存されている。  注文情報照会機能には、業務処理を実行するクラス(以下、ビジネスロジッククラスという)及びリクエスト処理を実行するクラス(以下、サーブレットクラスという)が使用されている。注文情報照会機能が参照するデータベースのE-R図を図3に、Eさんが作成したビジネスロジッククラスのソースコードを図4に、サーブレットクラスのソースコードを図5に示す。
情報処理安全確保支援士試験(令和5年度 午後1 問01 図03)
情報処理安全確保支援士試験(令和5年度 午後1 問01 図04)
情報処理安全確保支援士試験(令和5年度 午後1 問01 図05)
 D主任、Eさん、Fさんは、不具合の原因が特定できず、セキュアプログラミングに詳しい技術課の Hさんに協力を要請した。  Hさんはアプリケーションログ及びソースコードを解析し、不具合の原因を特定した。原因は、図4で変数 ef として宣言されていることである。  この不具合は、①並列動作する複数の処理が同一のリソースに同時にアクセスしたとき、想定外の処理結果が生じるものである。  原因を特定することができたので、Eさんは、Hさんの支援の下、次の4点を行った。
 (1)図4の2行目から5行目までのソースコードを削除する。  (2)図4の6行目を、図6に示すソースコードに修正する。
情報処理安全確保支援士試験(令和5年度 午後1 問01 図06)
(3)図5の4行目と5行目を、図7に示すソースコードに修正する。
情報処理安全確保支援士試験(令和5年度 午後1 問01 図07)
(4)保険的な対策として、図4の10行目の抽出条件に、セッションオブジェクトに保存されたjと注文ヘッダーテーブルのjの完全一致の条件をAND条件として追加する。   ソースコードの修正後、改めてシステムテストを実施した。システムテストの結果は良好であり、システムがリリースされた。

設問1ツールによるソースコードの静的解析について答えよ。

(1)表1中のaに入れる適切な行番号を、図1中から選び、答えよ。

模範解答

a:13

解説

解答の論理構成

  1. 静的解析ツールの指摘は「ディレクトリトラバーサル」であり、 「ファイルアクセスに用いるパス名の文字列作成で、利用者が入力したデータを直接使用している。」と説明されています。
  2. 図1のソースコードを確認すると、入力値 inOrderNo を含めて OS のパス文字列を生成している箇所は次の行です。
    13: File fileObj = new File(PDF_DIRECTORY + "/" + clientCode + "/" + "DeliverySlip" + inOrderNo + ".pdf");
    ここで inOrderNo はサーブレットから受け取った利用者入力であり、パスに直接連結されています。
  3. 以上より、a に該当する行番号は「13」と判断できます。

誤りやすいポイント

  • 行「12: String clientCode …」を選んでしまうケース
    • clientCode も文字列ですが、ディレクトリ名生成そのものは行 13 で行われます。
  • 「SQL インジェクション」の修正箇所(8〜11 行目)と混同するケース
    • 同じ入力値 inOrderNo を扱っているため要注意です。
  • 「ファイル存在確認 → 入力チェック済み」と早合点するケース
    • 存在確認の前にファイルパスが生成されている点を見落としがちです。

FAQ

Q: 「clientCode」も入力値ですが、なぜ 12 行目ではなく 13 行目なのですか?
A: 12 行目はデータベースから値を取り出す処理であり、まだパス操作を行っていません。実際にパスを合成しているのは 13 行目です。
Q: ディレクトリトラバーサルは絶対パスでなければ発生しないのでは?
A: 相対パスでも ../../ などを含めれば親ディレクトリへ遷移できます。文字列連結でガードしていない以上、脆弱性は存在します。
Q: 入力チェックを後段で行えば問題ありませんか?
A: パス生成前にホワイトリスト方式で検証するのが基本です。後段で検出できなかった場合、攻撃が成立してしまいます。

関連キーワード: ディレクトリトラバーサル、静的解析、パス操作、入力値検証、セキュアコーディング

設問1ツールによるソースコードの静的解析について答えよ。

(2)表1中のbに入れる適切な変数名を、図1中から選び、答えよ。

模範解答

b:in

解説

解答の論理構成

  1. 表1の指摘内容には「変数 stmt、変数 resultObj、変数bが指すリソースが解放されない。」とあります。
  2. 図1のリソース生成箇所を確認すると、次の3種類のリソースが生成されています。
    • 10行目:Statement stmt = conn.createStatement();
    • 11行目:ResultSet resultObj = stmt.executeQuery(sql);
    • 14行目:BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileObj));
  3. 表1で既に列挙済みの stmt と resultObj に続く“3番目のリソース”は、図1の14行目で生成された BufferedInputStream 型の変数です。ここで使われている変数名は「in」です。
  4. よって、b に入る適切な変数名は「in」になります。

誤りやすいポイント

  • buf と回答してしまう
    • byte[] buf = new byte[in.available()] はメモリ領域の確保であり、ファイルやストリームのような「外部リソース」ではないため解放対象ではありません。
  • fileObj と回答してしまう
    • File オブジェクト自体はディスクリプタを保持せず、明示的な close は不要です。
  • ソース全体を見ずに行番号だけに着目する
    • 表1の指摘は行番号ではなく「リソース解放漏れ」に関する網羅性を問うため、登場する全てのリソース型変数を確認する必要があります。

FAQ

Q: どうして BufferedInputStream を close しなければならないのですか?
A: 入出力ストリームは OS のファイルディスクリプタを使用します。close しない場合、ディスクリプタが枯渇し、他の処理がファイルを開けなくなる恐れがあります。
Q: try-with-resources を使えば解放漏れは防げますか?
A: はい。Java7 以降であれば try (BufferedInputStream in = …) のように書くことで、例外が発生しても自動的に close されます。
Q: File クラスはなぜ解放が不要なのですか?
A: File オブジェクトはファイルシステム上のパスを表すだけであり、実際のファイルハンドルを保持しないため、クローズ処理は必要ありません。

関連キーワード: ストリーム、リソース解放、try-with-resources, ファイルディスクリプタ

設問1ツールによるソースコードの静的解析について答えよ。

(3)図2中のcdに入れる適切な字句を答えよ。

模範解答

d:PreparedStatement stmt = conn.prepareStatement(sql)

解説

解答の論理構成

  1. 静的解析ツールが指摘した項番1は「SQL インジェクション」です。図1の
    sql = sql + " WHERE head.order_no = '" + inOrderNo + "' ";
    という記述は、利用者入力 inOrderNo を文字列連結しており、攻撃者が任意の SQL を注入できる危険があります。
  2. 図2ではこの脆弱性を除去するため、SQL 文にプレースホルダを用いて PreparedStatement でバインド方式に変更しています。したがって c には「プレースホルダ付き WHERE 句」をそのまま文字列として設定する必要があります。
    ・従来の文字列連結部分をそのまま残すと意味がない
    ・setString で 1 番目のパラメータへ inOrderNo を束縛するため、? が 1 個だけ必要
    よって c
    WHERE head.order_no = ?
    が適切です。
  3. Statement を生成していた 10 行目もプレースホルダ処理に合わせて PreparedStatement に置き換えます。図2の d には
    PreparedStatement stmt = conn.prepareStatement(sql)
    が入ることが示されています(模範解答より)。
  4. 最終的に、 java sql = sql + " WHERE head.order_no = ? "; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, inOrderNo);
    という形になり、ユーザ入力が SQL 文に直接挿入されないため、指摘事項「SQL インジェクション」が解消されます。

誤りやすいポイント

  • プレースホルダ ? の前後に引用符 ' を残す
    (例:WHERE head.order_no = '?')とバインド時に型不一致や検索失敗を招きます。
  • PreparedStatement 生成後に executeQuery(sql) を呼び出す
    (正しくは executeQuery())。ツールでは検出されても実行時にエラーになります。
  • setString の添字を 0 から始めると java.sql.SQLException が発生します。Java の JDBC は 1 始まりです。

FAQ

Q: 単に WHERE head.order_no = ' で始めて最後に ' を付け、その間を ? と置き換えてはだめですか?
A: その方法だとプレースホルダがシングルクォートで囲まれた文字列リテラル扱いとなり、JDBC が値をバインドできません。? だけを記述し、JDBC ドライバに型とエスケープ処理を任せるのが正しい実装です。
Q: PreparedStatement にしても SQL を連結する別の場所が残っていると危険ですか?
A: はい。PreparedStatement を使用しても、プレースホルダ以外の部分にユーザ入力を連結してしまうと、同様の SQL インジェクションが発生します。全てのユーザ入力は必ずバインド変数に設定することが重要です。
Q: 単純な検索なので入力チェックだけで良いのでは?
A: 文字列検証は有効ですが完全ではありません。入力チェック+プリペアドステートメントの多層防御でリスクを最小化することが推奨されます。

関連キーワード: SQLインジェクション、PreparedStatement, プレースホルダ、バインド変数、静的解析

設問2システムテストについて答えよ。

(1)本文中のeに入れる適切な変数名を、図4中から選び、答えよ。

模範解答

e:orderNo

解説

解答の論理構成

  • 【問題文】には「原因は、図4で変数 ef として宣言されていることである。」とある。
  • 図4の2行目には「private static String orderNo; //注文番号」と記載されており、ここで使われている変数名が e に該当する。
  • したがって e に入る変数名は「orderNo」となる。
  • さらに図4の8行目以降で「psObj.setString(1, orderNo);」と利用されていることから、注文番号を保持する目的の変数であると確認できる。
  • 以上より、e の正答は【 orderNo 】となる。

誤りやすいポイント

  • 静的解析で指摘された納品書PDFダウンロードクラス(図1・図2)と、今回問われているビジネスロジッククラス(図4)を混同してしまう。
  • 「static」の有無だけに注目し、変数名を見落とすと「orderNo」以外のキーワードを記入してしまう。
  • 図5のサーブレット側にも「orderNo」が局所変数で登場するため、両者を区別しないと混乱しやすい。

FAQ

Q: なぜ「static」が付いていると不具合になるのですか?
A: 複数スレッド(複数ユーザ)が同時にアクセスする場合、クラス変数は共有されるため、先にセットした注文番号が後続処理で上書きされ、別ユーザのデータが返却される競合が起きるからです。
Q: サーブレット側で new したオブジェクトに移行したのはどのような意図ですか?
A: インスタンス変数にすれば各リクエストごとに独立した値を保持できるため、スレッドセーフになり誤動作を防止できます。
Q: セッションオブジェクトで得意先コードを AND 条件に追加した理由は?
A: 万一ロジック層に再び競合が発生しても、データベース検索結果が他得意先に漏れないように“保険的”に絞り込むためです。

関連キーワード: 共有変数、スレッドセーフ、同期不良、クラス変数、インスタンス化

設問2システムテストについて答えよ。

(2)本文中のfに入れる適切な字句を、英字10字以内で答えよ。

模範解答

f:static

解説

解答の論理構成

  • 【問題文】には「原因は、図4で変数 ef として宣言されていることである。」とあり、図4の2行目には
    2: private static String orderNo;
    と示されています。ここから f に入る語が static であることが読み取れます。
  • static 修飾子で宣言したフィールドはクラスに一つしか存在せず、全スレッド・全インスタンスで共有されます。
  • 【問題文】では不具合の性質を「①並列動作する複数の処理が同一のリソースに同時にアクセスしたとき、想定外の処理結果が生じる」と説明しています。orderNo が共有されてしまうため、あるリクエストが OrderInfoBL.setOrderNo で値を設定した直後に、別のリクエストが上書きし、最初のリクエストが誤った注文番号で検索を実行する ―― まさに並行アクセスによるレースコンディションです。
  • よって f には static が入ります。

誤りやすいポイント

  • private や String といったキーワードを原因と勘違いし、アクセス修飾子や型に意識が向き過ぎる。
  • static メソッドと static フィールドを混同し、「メソッドが static だから問題」と誤解する。実際の不具合はフィールド共有によるものです。
  • 「Servlet はシングルスレッドで動く」と思い込み、マルチスレッド環境でのクラス変数共有問題を軽視する。

FAQ

Q: static を外せば必ず安全になるのでしょうか?
A: インスタンスフィールドに変更することで少なくともスレッド間で値を共有しなくなり、今回の誤動作は防げます。ただし、他に共有リソースがある場合は別途排他制御が必要です。
Q: synchronized でメソッドを囲めば static のままでも良いのでは?
A: 排他制御で競合は防げますが、全リクエストが同じロックを待つことになり性能劣化の原因になります。本設計ではリクエストごとに独立した値を持たせる方が適切です。
Q: Servlet で状態を持つときはどうすれば良い?
A: セッションスコープやリクエストスコープなど、スレッドごとに分離された領域に保存してください。共有が必要な場合だけスレッドセーフな構造(例:ConcurrentHashMap)を使います。

関連キーワード: 共有変数、レースコンディション、スレッドセーフ、セッション管理、サーブレット

設問2システムテストについて答えよ。

(3)本文中の下線①の不具合は何と呼ばれるか。15字以内で答えよ。

模範解答

レースコンディション

解説

解答の論理構成

  1. 【問題文】では「①並列動作する複数の処理が同一のリソースに同時にアクセスしたとき、想定外の処理結果が生じる」と明記されています。
  2. この現象は、処理(スレッドやプロセス)間でリソース共有の同期が取れていないために発生します。
  3. コンピュータシステムの典型的な障害分類では、上記のような“同時アクセスによる競合”を「レースコンディション」と呼びます。
  4. よって、設問の下線①の不具合名は「レースコンディション」と判断できます。

誤りやすいポイント

  • 「デッドロック」と混同する
    同期が取れていない点は同じですが、デッドロックは“お互いがロックを待ち続けて停止する”状態であり、想定外のデータ混在や上書きは起きません。
  • 「クリティカルセクション」がキーワードだと思い違いする
    クリティカルセクションは対策概念であり、不具合名ではありません。
  • “競合状態”を日本語そのままで書いてしまう
    出題は正式な用語を求めているため、「レースコンディション」と記述する必要があります。

FAQ

Q: レースコンディションはマルチスレッド環境だけの問題ですか?
A: いいえ。マルチプロセスや分散処理など複数主体が同一リソースにアクセスするすべての場面で起こり得ます。
Q: 防止策はロックを掛けるだけで十分ですか?
A: 排他制御(ロック、同期化)は基本対策ですが、タイムアウト設定やトランザクション分離レベルの見直しも重要です。
Q: ログ調査でレースコンディションをどう見抜くのですか?
A: 同一リソースに対するアクセス時刻が極端に近接し、処理結果が交互に上書きされている痕跡などがヒントになります。

関連キーワード: race condition, concurrency, synchronization, shared resource

設問2システムテストについて答えよ。

(4)図6中のg、図7中のhiに入れる適切な字句を答えよ。

模範解答

i:getOrderInfoBean(orderNo)

解説

解答の論理構成

  • 【問題文】では、並列アクセスによる不具合の原因を「図4で変数 ef として宣言されている」ことと説明し、対策として
    (1)「図4の2行目から5行目までのソースコードを削除する。」
    (2)「図4の6行目を、図6に示すソースコードに修正する。」
    (3)「図5の4行目と5行目を、図7に示すソースコードに修正する。」
    と指示しています。
  • まず(1)で削除されるのは
    private static String orderNo; public static void setOrderNo(String inOrderNo) { … }
    すなわち static フィールドと static セッタです。よって以降は「インスタンスメソッドに引数で注文番号を渡す」形に改めなければなりません。
  • (2)の図6は「public OrderInfoBean getOrderInfoBean(g) {」という宣言のみ示されており、ここに入るのは「呼び出し側(サーブレット)から渡される注文番号」の型と変数名です。メソッド本体には既に
    psObj.setString(1, orderNo);
    という参照が残っているため、パラメータ名は orderNo でなければコンパイルできません。型は文字列なので String orderNo となります。したがって
    g:String orderNo
  • (3)の図7 1 行目はインスタンス生成文を示しており、Java でオブジェクトを生成するキーワードは new しかありません。
    h:new
  • 同じく図7 2 行目はインスタンスメソッド呼出しであり、引数に注文番号を渡しているため
    i:getOrderInfoBean(orderNo)
    となります(【模範解答】もこれを示しています)。

誤りやすいポイント

  • 「static の削除」=「そのまま static 呼出しをインスタンス呼出しに変えるだけ」と思い込み、メソッドに引数を追加し忘れる。
  • 図4内部の orderNo 参照を見落とし、パラメータ名を inOrderNo などにしてしまいコンパイルエラーになる。
  • Java のインスタンス生成キーワードを new() と書く、あるいは OrderInfoBL() だけにしてしまうミス。

FAQ

Q: メソッドを static のままにして、引数で注文番号を渡すだけでは駄目なのですか?
A: static メンバは JVM 全体で共有されるため、並列処理で同一メソッドを呼び出すと「最後にセットされた注文番号」に上書きされ、今回の不具合が再発します。インスタンス化してスレッド毎に独立した領域を持たせることが根本対策です。
Q: なぜパラメータ名を orderNo とするのですか?
A: 図4の既存コードに psObj.setString(1, orderNo); という行が残っているため、メソッド内で同じ識別子が必要です。名前を変えるなら内部参照もすべて修正する必要があります。
Q: インスタンス生成をシングルトンにすれば static でも良いのでは?
A: シングルトンは結局 1 つのインスタンスを全スレッドで共有します。スレッドセーフな実装や注文番号を局所変数に渡す仕組みを別途組み込まなければ今回の競合は防げません。

関連キーワード: 競合状態、スレッドセーフ、インスタンスメソッド、引数受け渡し、オブジェクト生成

設問2システムテストについて答えよ。

(5)本文中のjに入れる適切な属性名を、図3中から選び、答えよ。

模範解答

j:得意先コード

解説

解答の論理構成

  1. セッションに保持されている情報を確認
    • 【問題文】「ログイン処理時に、ログインした利用者IDと、利用者IDにひも付く得意先コード及び得意先名はセッションオブジェクトに保存されている。」
      ⇒ セッションには「得意先コード」が格納済みです。
  2. 追加すべき抽出条件の指示内容を確認
    • 【問題文】「図4の10行目の抽出条件に、セッションオブジェクトに保存されたjと注文ヘッダーテーブルのjの完全一致の条件をAND条件として追加する。」
      ⇒ セッションにある属性と注文ヘッダーテーブル上の同一属性を照合する必要があります。
  3. 注文ヘッダーテーブルに存在する対応属性を確認
    • 【図3】注文ヘッダーテーブルの属性一覧に「得意先コード」が存在。
    • 利用者マスターにも「得意先コード」が存在し、セッション保持情報とも一致。
  4. 上記 1〜3 から、セッションと注文ヘッダーテーブルの両方に共通に存在し完全一致を取るべき属性は「得意先コード」であると結論付けられます。

誤りやすいポイント

  • 「利用者ID」と誤認する
    セッションには利用者IDも保存されますが、注文ヘッダーテーブルには利用者IDが存在しないため抽出条件に使えません。
  • 「注文番号」を選択する
    既に WHERE 句で完全一致条件が設定済み(図4 13行目)なので追加条件には該当しません。
  • 「得意先名」を選ぶ
    文字列表記ゆれや重複のリスクがあり、リレーションも外部キーではないため誤りです。

FAQ

Q: 「得意先コード」をAND条件に加えるとどのような効果がありますか?
A: ログイン中の得意先に属する注文だけを抽出でき、別得意先の注文情報が誤って取得・表示されることを防ぎます。
Q: 既に注文番号で検索しているのに追加条件が必要な理由は?
A: 静的変数の共有などプログラムミスが残る可能性に備えた保険的対策として、得意先コードでも絞り込むことで多層防御となります。
Q: 得意先コードをパラメータ化せずにSQL文字列へ連結してもよいですか?
A: SQLインジェクション対策としてパラメータ化(PreparedStatementなど)を行い、得意先コードもバインド変数で渡すべきです。

関連キーワード: セッション管理、AND条件、外部キー、多層防御、SQLインジェクション
戦国ITクイズ機能

\ せっかくなら /

情報処理安全確保支援士
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてプライバシーポリシー利用規約特商法表記開発者について