SC午後の記述式は、単語を暗記していれば解けるものではありません。事例(シナリオ)の中に埋め込まれた「設計上の抜け」を読み解き、なぜそこが穴になるのかを自分の言葉で説明できて初めて点になります。この新シリーズ「SC午後問題 事例解説」では、実際の午後問題のテーマを架空事例に置き換えて、設問・回答例・採点ポイント・頻出パターンまでを一気通貫で解説します。
第1弾は、令和7年度 秋期(2025年10月)SC午後 問1のテーマであるコンサルティング業務で利用するSaaSを題材にします。中心となるのは格納型XSS(ストアドXSS)とファイルアップロード機能の検証不備です。
私がCIOを務めていた頃、自社Webサイトを守る手段としてWAFは高価で運用ハードルも高く、導入を見送りました。代わりにWebサーバー側のアクセス制御をハードニングして泥臭く守っていたのですが、当時から「入力を受け付ける画面」と「ファイルを受け取る機能」は最も神経を使う場所でした。この2つはいまもWebアプリの二大攻撃面であり、SC午後で繰り返し問われる王道テーマです。
この記事で学べることは次のとおりです。
- 格納型XSSがどの経路で成立し、なぜ「出力時のエスケープ」が正解になるのか
- ファイルアップロード機能に必要な多層の検証(拡張子・Content-Type・マジックバイト・保存先分離・実行防止)
- 同一オリジンにアップロードしたファイルがCSPをすり抜けてスクリプト実行される怖さ
- 記述式でどこに触れれば加点され、どこで失点しやすいか
なお本記事はXSSの基礎解説やSQLインジェクション解説の既存記事とは異なり、午後問題の事例をどう読み解き、どう記述で得点するかに振り切った「事例解説」の切り口です。仕組みそのものをまだ固めたい方は、先にXSSの3分類とブラックリストが通用しない理由を扱った基礎記事を読んでから戻ってくると効果的です。
事例シナリオ:コンサルSaaSで元従業員が仕掛けた攻撃
まずは架空のA社を舞台にしたシナリオを読んでください。設問はこの事例の中から出します。実際の午後問題と同じように、「どこが穴か」を意識しながら読み進めてください。
なお、本記事に登場するドメイン名・IPアドレス・ファイル名は、プライバシー保護のためすべて架空値に加工しています。ドメインは example.jp と表記します。
登場するシステムと利用者
A社は経営コンサルティングを手掛ける企業で、クライアントごとのプロジェクト情報を管理するために、自社開発のSaaS「PJ管理サービス」(https://pj.example.jp)を運用しています。主な機能は次のとおりです。
- プロジェクト進捗管理画面:担当コンサルタントがタスク名・コメントを登録し、同じプロジェクトのメンバーと管理者が閲覧する
- ファイル共有機能:提案書や見積書(Excel・PDF)をアップロードし、
https://pj.example.jp/files/配下から各メンバーがダウンロードする
利用者には「一般利用者(コンサルタント)」と「管理者」の2つの権限があります。管理者はすべてのプロジェクトの情報を閲覧でき、利用者アカウントの追加・削除もできる強い権限を持ちます。
このSaaSはセキュリティ対策として、HTTPレスポンスヘッダーにContent-Security-Policy: default-src 'self'を設定しており、外部ドメインから読み込まれるスクリプトは実行されない構成になっていました。

攻撃の発端
半年前にA社を退職した元コンサルタントZ氏は、退職後もアカウントが無効化されず、一般利用者としてpj.example.jpにログインできる状態のままでした。Z氏は管理者権限を奪い、担当外だったクライアントの機密情報を持ち出そうと考えます。
Z氏がまず目をつけたのが、ファイル共有機能でした。この機能はアップロードされるファイルについて拡張子が許可リスト(.xlsx、.pdf)に含まれるかどうかだけを確認しており、ファイルの中身は検査していませんでした。そこでZ氏は、中身がJavaScriptでありながらファイル名をteian_XXXXX.xlsxとした偽装ファイルを用意し、アップロードします。このファイルはhttps://pj.example.jp/files/teian_XXXXX.xlsxとして保存されました。
格納型XSSの発火
次にZ氏は、自分が参加できるプロジェクトの進捗管理画面で、タスク名として次の文字列を登録しました。
<script src="/files/teian_XXXXX.xlsx"></script>
この画面は、登録されたタスク名をエスケープせずにそのままHTMLとして出力していました。そのため、管理者がこのプロジェクトの進捗を確認しようと画面を開いた瞬間、タスク名がタグとして解釈され、/files/teian_XXXXX.xlsxの中身がスクリプトとして読み込まれて実行されました。
読み込み元は外部ドメインではなくpj.example.jp自身(同一オリジン)だったため、default-src 'self'のCSPをすり抜けます。実行されたスクリプトは、管理者のセッションを使って新しい管理者アカウントを密かに追加し、Z氏はそのアカウントで全クライアントの機密情報にアクセスしました。

今日どこを学ぶか=毎日の道しるべになる
セキュリティ学習
設問
事例を踏まえて、次の設問に記述で答えてください。実際の午後問題と同じように、字数や要点の絞り込みを意識してください。
設問1
本事例で成立した格納型XSS(ストアドXSS)について、攻撃コードがどのように保存され、どの利用者のブラウザで、いつ実行されたかを、格納型XSSの特徴を踏まえて説明してください。
設問2
このSaaSではContent-Security-Policy: default-src 'self'を設定していたにもかかわらず、攻撃スクリプトが実行されました。CSPをすり抜けることができた理由を説明してください。
設問3
プロジェクト進捗管理画面の格納型XSSを根本的に防ぐために、どの処理を、どのタイミングで実施すべきか答えてください。あわせて、ファイル共有機能に追加すべき検証・対策を3つ挙げてください。
回答例
記述式の模範解答は、事実を漏らさず、かつ冗長にしないのがコツです。以下は要点を押さえた解答例です。
設問1の回答例
攻撃者が進捗管理画面のタスク名としてscriptタグを含む文字列を登録し、その値がエスケープされずにデータベースに保存された。保存された値は、同じプロジェクトの進捗管理画面を開いた管理者のブラウザ上で、画面表示時にHTMLとして解釈されて実行された。攻撃コードがサーバー側に永続的に保存され、閲覧した別の利用者のブラウザで発火する点が格納型XSSの特徴である。
設問2の回答例
default-src 'self'は'unsafe-inline'を含まないため、タスク名に直接<script>...</script>を書いてもインラインスクリプトとして実行はブロックされる。そこで攻撃者は、アップロード機能でpj.example.jp配下(/files)に保存した同一オリジンのファイルを用意し、タスク名のscriptタグからそのファイルをsrcとして参照させた。default-src 'self'は自オリジンからの読み込みを許可するため、同一オリジンに置かれたファイルの読み込みと実行は制限できず、CSPをすり抜けた。
設問3の回答例
XSS対策:タスク名をHTMLとして画面に出力するタイミングで、<・>・&・"などの特殊文字をHTMLエスケープしてから出力する。入力時ではなく、出力時(画面表示時)にその出力先の文脈に応じたエスケープを行う。
ファイル共有機能に追加すべき対策(3つ):
- 拡張子だけでなく、Content-Type(MIMEタイプ)とファイル先頭のマジックバイトを検証し、許可された形式(Excel・PDF)の実体と一致しないファイルを拒否する
- アップロードされたファイルを公開ディレクトリやアプリケーションと同一オリジンで実行・解釈させない。保存先をWeb公開領域の外に分離し、ダウンロード時は
Content-Disposition: attachmentを付与して常にダウンロード扱いにする(別オリジンのドメインから配信する構成も有効) - サーバー側でファイルにスクリプトとしての実行権限を与えず、ファイル名は推測困難な値へ再割り当てして直接参照を防ぐ

採点ポイント
ここが本シリーズの肝です。同じ内容を書いても、要点に触れているかどうかで部分点が大きく変わります。
加点される要点
- 設問1:「サーバー側(DB)に保存される」「閲覧した別の利用者のブラウザで実行される」の2点を両方書くこと。格納型は、反射型(リクエストに含めた値がその場で返る)や、DOM Based(クライアント側のJavaScriptがDOMを書き換えて発火する)との違いが「保存される/別の利用者に届く」点にあります。ここを明示すると採点者に分類の理解が伝わります。
- 設問2:「同一オリジンに置かれたファイルを参照している」「
'self'は自オリジンを許可するので防げない」という因果を書くこと。CSPを設定していれば安全という思い込みを崩せているかが見られます。 - 設問3のXSS:「出力時にエスケープする」と書けているか。ここが最大の分岐点です。
よくある減点・失点パターン
第一の失点は、設問3のXSS対策で「入力時にエスケープする」と書いてしまうことです。エスケープすべき内容は出力先の文脈(HTML本文/属性値/JavaScript/URL)によって変わるため、入力時に一律エスケープすると、別の用途で使うときに壊れたり、逆に無害化が不十分になったりします。正解は「出力時に、その出力コンテキストに応じてエスケープする」です。入力時エスケープは、出力先の文脈が確定していない段階で一律に処理してしまうため無害化漏れや表示崩れを招きやすく、記述式でも「出力時にコンテキストに応じてエスケープ」と書けているかが加点の分岐点になります。
第二の失点は、ファイルアップロード対策を「拡張子をチェックする」だけで止めてしまうことです。事例では拡張子チェックはすでに実装済みで、それでも突破されています。設問が「追加すべき検証」を問うている以上、既存の拡張子チェックを答えても加点されません。Content-Type・マジックバイトによる中身の検証、そして「実行・解釈させない」保存側の対策までセットで書けているかが分かれ目です。
第三の失点は、対策を入口検証だけで完結させてしまうことです。仮に検証をすり抜けられても、保存先の分離やContent-Dispositionによって「実行させない」多層防御があれば被害を防げます。入口(検証)と出口(実行防止)の両面に触れると解答に厚みが出ます。
字数調整のコツ
午後は字数指定がある設問と、具体的に述べさせる設問が混在します。字数が短いときは主語と動詞を削らず、修飾語を削ります。「攻撃者が保存したscriptタグが、管理者の画面表示時に実行された」のように、誰の・どの操作で・いつ発火したかの骨格を最優先で残してください。
頻出パターン
このテーマはSC午後で繰り返し問われます。本番で素早く見抜くための「型」を整理します。
XSS3分類の識別を問う型
XSSが出たら、まず格納型・反射型・DOM Basedのどれかを事例から判定させる設問が来ると身構えてください(3分類の詳しい違いはXSSの3分類を図解した基礎記事で整理しています)。判定の決め手は次のとおりです。
- 格納型:入力値がサーバー側(DB・ファイル)に保存され、後から別の利用者が閲覧したときに発火する。掲示板・コメント・プロフィール・タスク名など「他人が見る保存データ」が舞台になりやすい
- 反射型:リクエストに含めた値が、その応答画面にそのまま出力されて発火する。攻撃URLを踏ませる手口とセットで問われる
- DOM Based:サーバーを介さず、クライアント側のJavaScriptが
locationやinnerHTMLなどを通じてDOMを書き換えることで発火する
事例で「保存」「他の利用者が見る」という言葉が出たら格納型を疑う、というだけで初動が速くなります。
エスケープの「場所」を問う型
XSS対策の設問は、ほぼ必ず「どのタイミングでエスケープするか」を問います。答えは一貫して出力時です。さらに一歩踏み込むと、出力先がHTML属性値ならHTML属性用、JavaScript内ならJavaScript文字列用、URLパラメータならURLエンコードと、出力コンテキストごとにエスケープ方法を変えるのが正確な理解です。「出力時にコンテキストに応じてエスケープ」をワンフレーズで書けるようにしておくと強いです。なお同じ「エスケープ」でも、SQLインジェクション対策ではエスケープよりプレースホルダ(プリペアドステートメント)が正解になります。XSSとSQLiでエスケープの立ち位置が違う点は、記述で取り違えやすいので押さえておいてください。
ファイルアップロード対策の定番セットを問う型
ファイルアップロード機能が出たら、次の定番セットを頭から取り出せるようにしておきます。
- 入口の検証:拡張子(許可リスト方式)+Content-Type+マジックバイトの三点で中身を確認する
- 保存側の実行防止:Web公開領域の外に保存する/実行権限を与えない/推測困難なファイル名に変える
- 配信時の制御:
Content-Disposition: attachmentで常にダウンロード扱いにする/アプリ本体とは別オリジンのドメインから配信する - 容量・件数の制限:巨大ファイルによるサービス妨害(DoS)を防ぐ上限設定
これらは「入口・保存・配信」の3レイヤーで覚えると、設問が何を問うても引き出せます。
CSPを過信させない型
近年は「CSPを入れているのに突破された、なぜか」という一歩踏み込んだ問い方が増えています。見抜き方はシンプルで、攻撃スクリプトの読み込み元が自オリジンかどうかを確認することです。'self'は自オリジンを許可するため、アップロードしたファイルを同一オリジンから<script src>で読み込む手口や、許可した外部CDNに置かれた危険なライブラリ経由の実行は防げません。CSPは多層防御の一枚であって単独の万能策ではない、という前提で読むと引っかかりません。
この事例が実務と直結する理由
私がCIOだった頃も、外部とファイルをやり取りする経路は常に最大の懸念でした。SaaSでクライアントと成果物を共有する今の時代は、アップロード機能と入力画面がそのまま攻撃面になります。試験の事例は机上の空論ではなく、退職者アカウントの放置・入口検証の甘さ・出力エスケープ漏れという、現場でそのまま起こりうる複合的な失敗を凝縮したものです。設問の一つひとつを「自社のSaaSならどう直すか」に置き換えて読むと、記述の解像度が上がります。
まとめ:事例を「自社ならどう直すか」に翻訳して読む
令和7年秋 午後問1のテーマである格納型XSSとファイルアップロード検証不備は、Webアプリの二大攻撃面を同時に問う良問でした。押さえるべき骨格はシンプルです。XSSは出力時にコンテキストに応じてエスケープ、ファイルアップロードは入口の中身検証と保存側の実行防止をセットで、そしてCSPは万能ではなく自オリジン経由はすり抜けるという3点です。
私が新卒エンジニアに基盤を教えていた頃、彼らが最初につまずくのは「入力さえチェックすれば安全」という思い込みでした。実際には、入口をすり抜けられても被害を出さない出口側の設計(保存先の分離、出力時エスケープ、実行防止)まで組んで初めて防御になります。この「入口と出口の両輪」という視点は、SC午後の記述で必ず効いてきます。事例を読むときは、犯人探しで終わらせず「自分が管理者ならどの処理を、どのタイミングで直すか」まで言語化する練習を重ねてください。それがそのまま午後の得点力になります。
本記事は情報処理安全確保支援士(SC)試験対策を目的として作成しています。
参考資料
- IPA 情報処理安全確保支援士試験 過去問題(令和7年度秋期):https://www.ipa.go.jp/shiken/mondai-kaiotu/2025r07.html
- 本記事は令和7年度 秋期 午後 問1(コンサルティング業務で利用するSaaS)をテーマにした事例解説です。詳細な設問・解答例は上記の公式PDFを参照してください。本文中の事例は著作権に配慮し、テーマに沿って独自に作成した架空シナリオです。
- IPA 安全なウェブサイトの作り方(クロスサイト・スクリプティング/ファイルのアップロード対策):https://www.ipa.go.jp/security/vuln/websecurity/about.html
今日どこを学ぶか=毎日の道しるべになる
セキュリティ学習