令和4年度 春期 情報処理安全確保支援士試験 午後Ⅰ 問1 Webアプリのプロジェクト情報共有におけるアクセス制御不備と安全な実装
テクノロジセキュリティ技術
学習ガイド
社内の情報共有システムを改修し、プロジェクト単位のアクセス制御を追加する場面を題材にした問題です。URLのクエリ文字列を介して認可情報を渡す設計の欠陥と、セッション管理を用いた安全な実装への見直し、SQLの検索条件によるアクセス制御の徹底が問われます。まずは改修方針と表2の画面遷移からパラメータが外部から改変できる構造を読み取り、図2と図3のソースコードおよび図1のE-R図を照合して、認可の漏れを防ぐ条件式を導きましょう。
この記事で押さえる論点
- クエリ文字列のパラメータ改ざんによるアクセス制御のバイパス手口を説明できる
- 認可情報をクライアント側から渡さずセッション情報で管理する重要性を述べられる
- リソース参照時に所属プロジェクトの識別子をSQLの抽出条件に含める必要性を説明できる
- プレースホルダや改行コード検査などWebアプリ脆弱性検査の基本手法を述べられる
出題情報
- 出題
- 2022(R4)春 情報処理安全確保支援士 午後I 問1
- 配点
- 50点満点
- 模範解答
- 公表(設問ごとに掲載)
出題趣旨・採点講評(IPA 公表)
システム開発においては,要件定義からテストまでの全てのプロセスでセキュリティ対策が必要であることは広く認識されている。一方で,アクセス制御における設計上の考慮不足や実装の不備による情報流出の被害事例が後を絶たない。たとえアクセス制御が単純なものであっても,問題が発生しているのが現実である。 本問では,情報共有用Webアプリケーションプログラム開発のセキュリティ対策を題材として,システム開発の設計,実装,テストの各プロセスにおける脆弱性の分析及び修正に関わる能力を問う。
問1では,情報共有用のWebシステムの開発を題材に,システム開発における脆弱性の分析と対策方法について出題した。全体として正答率は平均的であった。
問題本文
問1 Webアプリケーションプログラム開発のセキュリティ対策に関する次の記述を読んで,設問1〜3に答えよ。
H社は,Webアプリケーションプログラム(以下,Webアプリという)を開発する従業員200名の会社である。H社では,開発部がWebアプリを開発し,情報セキュリティ部が,表1に示す方法に従って,脆弱性検査を実施する。

図の説明テキスト
表1 脆弱性検査の方法(抜粋)
項番1 HTTPヘッダインジェクション:
①改行コードを意味する文字列を入力したときに、HTTPヘッダフィールドが追加されないことを確認する。
項番2 SQLインジェクション:
②変数の場所を示す?記号を置く技法を利用する。
項番3 メールヘッダインジェクション:
aを削除する。
開発部では,自部で開発したSシステムというWebシステムを利用して,コーディングルールなどの社内ルールを含む各種の情報を共有している。Sシステムの利用者は,ログイン後に情報の投稿と表示を行うことができる。投稿された情報はデータベースに格納される。
ログインから情報表示までのSシステムの画面遷移を表2に示す。

図の説明テキスト
表2 ログインから情報表示までのSシステムの画面遷移
〔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に示す。

図の説明テキスト
図1 参照するデータベースのE-R図

図の説明テキスト
図2 修正後の情報選択機能のソースコード
8行目: java.sql.b stmt = con.prepareStatement(sql);
9行目: c.setInt(1, projectId);
〔情報表示機能の脆弱性〕
情報セキュリティ部は,情報表示機能にも情報選択機能と同様の脆弱性があることを指摘した。Dさんは,情報表示機能にも同様の修正を行った。修正後の情報表示機能のソースコードを図3に示す。

図の説明テキスト
図3 修正後の情報表示機能のソースコード
8行目: String sql = "SELECT 情報番号, 情報名, 情報内容 FROM 情報管理テーブル WHERE d";
9行目: java.sql.b stmt = con.prepareStatement(sql);
情報セキュリティ部による脆弱性検査に合格後,Sシステムの改修版がリリースされ,各プロジェクト内の情報共有が強化された。
設問と解答・解説
設問1
表1について,(1)〜(3)に答えよ。
表1中の下線①について,適切な文字列の例を,解答群の中から選び,記号で答えよ。
模範解答
選択肢ア: %0D%0A
解説
正解の根拠
表1の項番1「HTTPヘッダインジェクション」について問われています。HTTPヘッダインジェクションは、外部からの入力値にHTTPヘッダの区切り文字である 改行コード が含まれることで、意図しないレスポンスヘッダやボディが解釈されてしまう脆弱性です。
HTTPの仕様では、ヘッダの各行やヘッダとボディの境界を示す改行コードとして CRLF が用いられます。このCRLFをURLエンコードした文字列は %0D%0A となります。したがって、検査において改行コードを意味する文字列として入力すべきなのは %0D%0A です。
各選択肢の解説
ア: 正解。
%0D%0AはCRLFのURLエンコードであり、HTTPヘッダにおける改行コードを意味します。イ:
%20はスペース文字のURLエンコードであり、改行コードではありません。ウ:
はHTMLにおける改行タグです。講評でも指摘されている通り、これはHTMLの表示上の改行であり、HTTPヘッダの改行コードではありません。エ:
<p>はHTMLにおける段落を示すタグであり、改行コードではありません。
表1中の下線②について,名称を,10字以内で答えよ。
模範解答
プレースホルダ
採点基準
- 3点: SQLインジェクションの対策技法として「プレースホルダ」または同義の用語を理解している。
- 0点: 理解が不十分である、または無回答。
- 3点: 指定字数以内で、不要な語句を含まず明確に用語を提示できている。
- 0点: 語句として成立していない。
解説
正解の根拠
表1の項番2「SQLインジェクション」の対策方法について問われています。SQLインジェクションを防ぐための根本的な対策として、SQL文のひな形にあらかじめ変数の場所を示す ? 記号を置いておき、後から安全に値をバインドする手法があります。この技法は プレースホルダ (またはバインド機構)と呼ばれます。
高得点のポイント
- SQLインジェクション対策として用いられる「プレースホルダ」という専門用語を、正確に記述していること。
表1中の a に入れる適切な字句を,5字以内で答えよ。
模範解答
改行コード
採点基準
- 6点: 「改行コード」と解答している。
- 3点: 意味は通じるが、表記が異なる(例:「改行」など)。
- 0点: 全く異なる字句を解答している。
解説
正解の根拠
表1の項番3「メールヘッダインジェクション」の対策について問われています。メールヘッダインジェクションは、外部からの入力値に改行コードが含まれることで、意図しないメールヘッダ(Bccなど)や本文が追加されてしまう攻撃です。
これはHTTPヘッダインジェクションと同様に、ヘッダフィールドが改行によって区切られる仕様を悪用したものです。したがって、対策としては外部からの入力に含まれる 改行コード を削除することが有効です。
高得点のポイント
- メールヘッダの区切りとなる「改行コード」を削除すべきであると指摘できること。
設問1(1)は,正答率がやや低かった。ウのHTML改行タグの解答が多かった。HTTPとHTMLの理解が不十分である結果と想定される。
設問2
〔情報選択機能の脆弱性〕について,(1)〜(4)に答えよ。
本文中の下線③について,未参加のプロジェクトに参加しているかのように偽るための操作を,40字以内で具体的に述べよ。
模範解答
クエリ文字列のidに,未参加のプロジェクトのプロジェクトIDを指定する。
採点基準
- 3点: 偽装操作の対象が「クエリ文字列のid」などのパラメータであることを正確に特定している。
- 1点: 操作対象への言及が曖昧であるか、一部不足している。
- 0点: 操作対象について全く言及がない。
- 3点: パラメータに「未参加のプロジェクトのプロジェクトID」を指定するという改ざんの具体的な操作が論理的に記述されている。
- 1点: 操作の意図は伝わるが、具体的な値の指定方法の説明が不足している。
- 0点: 全く異なる操作内容が記述されている。
解説
正解の根拠
本文の〔情報選択機能の脆弱性〕における「方法1」のアクセス制御方法について問われています。
方法1では、「ログイン時にその利用者IDに対して登録されているプロジェクトIDを取得し,GETリクエストのクエリ文字列に,“id=プロジェクトID”の形式で指定する」としています。情報選択機能は、このクエリ文字列から受け取ったプロジェクトIDをチェックせずにそのまま利用して情報を表示しています。
したがって、そのプロジェクトに参加していない利用者が参加しているかのように偽るためには、攻撃者がGETリクエストを改ざんし、クエリ文字列のidに未参加のプロジェクトのプロジェクトIDを指定 して送信すればよいことになります。
高得点のポイント
GETリクエストの「クエリ文字列のid」を操作の対象として明記していること。
設定する値が「未参加のプロジェクトのプロジェクトID」であることを明記していること。
本文中の下線④について,方法1の脆弱性が方法2で解決されるのはなぜか。30字以内で述べよ。
模範解答
プロジェクトを示すパラメタを外部から指定できないから
セッション情報からプロジェクトIDを取得するから
採点基準
- 3点: プロジェクトを示すパラメタを外部から指定できないこと、またはセッション情報からプロジェクトIDを取得することが記述されている。
- 1点: 外部からの指定不可やセッション情報からの取得について言及しているが、記述が不十分である。
- 0点: 取得元やパラメタ指定についての言及がない、または誤っている。
- 3点: 方法1の脆弱性が方法2で解決される理由が、論理的かつ明確に説明されている。
- 1点: 解決理由は示されているが、論理のつながりが不明確である。
- 0点: 全く異なる理由が記述されている、または論理的に破綻している。
解説
解説
方法1の脆弱性が、方法2に変更することで解決される理由が問われています。
方法1では、アクセス制御の対象となるプロジェクトIDを利用者が改変可能なクエリ文字列から取得していたため、未参加のプロジェクト情報を閲覧できてしまう脆弱性がありました。
一方、方法2では、サーバ側で安全に管理されるセッション情報からプロジェクトIDを取得するように変更されています。これにより、利用者が外部からプロジェクトを指定するパラメタを操作できなくなります。
したがって、「プロジェクトを示すパラメタを外部から指定できないから」、または「セッション情報からプロジェクトIDを取得するから」という理由が成り立ちます。
高得点のポイント
- プロジェクトを示すパラメタを外部から指定できないこと、またはセッション情報からプロジェクトIDを取得することのいずれかを記述すること。
- 30字以内で簡潔に理由を述べること。
図2中及び図3中の b に入れる適切な字句を,解答群の中から選び,記号で答えよ。
模範解答
選択肢ウ: PreparedStatement
解説
正解の根拠
図2の修正後の情報選択機能のソースコードにおいて、8行目の空欄bに入る適切な字句が問われています。
図2の7行目では、SQL文のひな形として WHERE プロジェクトID = ? というようにプレースホルダ ? を利用しています。Java(JDBC)において、このプレースホルダを伴うSQL文の実行準備を行うためには、Connection オブジェクトの prepareStatement メソッドを呼び出します。8行目の stmt = con.prepareStatement(sql); によって生成されるオブジェクトの型(インタフェース)は PreparedStatement です。
各選択肢の解説
ア:
Connectionはデータベースとの接続を表すインタフェースであり、prepareStatementの戻り値ではありません。イ:
DriverManagerはJDBCドライバを管理するクラスであり、SQL文の実行準備を行うクラスではありません。ウ: 正解。
PreparedStatementは、プレースホルダを伴うSQL文を安全に実行するために使用されるインタフェースです。エ:
Statementは、プレースホルダを伴わない単純なSQL文を実行するためのインタフェースであり、今回の?を用いたバインド処理には対応していません。
図2中の c に入れる適切な字句を答えよ。
模範解答
stmt
採点基準
- 9点: 「stmt」と解答している。
- 0点: 誤った解答である。
解説
正解の根拠
図2の9行目の空欄cに入る字句が問われています。
8行目で con.prepareStatement(sql) によって生成された PreparedStatement オブジェクトは、変数 stmt に代入されています。9行目で、SQL文のプレースホルダ ? に対して projectId をバインドするためには、この stmt オブジェクトの setInt メソッドを呼び出す必要があります。したがって、空欄cには stmt が入ります。
高得点のポイント
- Javaにおけるメソッド呼び出しの構文を理解し、直前の行で宣言・初期化されたオブジェクト変数
stmtを正確に指定できること。
設問2(3)は,正答率がやや低かった。StatementでもSQLの実装は可能であるが,本文に示されているプレースホルダの実装にはStatementを継承したPreparedStatementが必要である。脆弱性対策手法については,理論や用語だけではなく,その具体的な方法を理解してほしい。
設問3
図3中の d に入れる適切な字句を,図1中の属性名を含めて答えよ。
模範解答
情報番号 = ? AND プロジェクトID = ?
採点基準
- 9点: 属性名「情報番号」と「プロジェクトID」の両方を含み、プレースホルダ「?」と「AND」を用いた正しい条件式(例:「情報番号 = ? AND プロジェクトID = ?」)を記述している。
- 4点: 属性名を用いた条件式を記述しているが、プレースホルダの記述漏れや、片方の条件のみとなっているなど一部不備がある。
- 0点: 属性名が正しくない、または解答が不適切である。
解説
正解の根拠
図3の修正後の情報表示機能のソースコードにおいて、8行目のSQL文のWHERE句(空欄d)に入る字句が問われています。
情報表示機能では、利用者が選択した情報(documentNo)を取得するだけでなく、情報選択機能と同様の脆弱性(他プロジェクトの情報の閲覧)を防ぐため、利用者が参加するプロジェクト(projectId)による絞り込みも行わなければなりません。
図1のE-R図より、「情報管理テーブル」は主キーとして「情報番号」を、外部キーとして「プロジェクトID」を持っています。したがって、取得すべき情報の条件は、指定された情報番号とプロジェクトIDの両方に一致することです。
SQLインジェクション対策としてプレースホルダ ? を用いる必要があるため、空欄dには 情報番号 = ? AND プロジェクトID = ? という条件式が入ります。
高得点のポイント
図1の「情報管理テーブル」の属性名である「情報番号」と「プロジェクトID」を両方使用していること。
それらを論理演算子
ANDで正しく結合していること。セキュリティ対策として、プレースホルダ
?を用いて条件式を記述していること。
設問3は,正答率がやや低かった。SQLの構文が誤っている解答が見受けられた。データベースのアクセス制御の設計,実装及びレビューを行うために,SQLの構文やE-R図の表記法を知っておいてほしい。