SC科目B(午後)のXSS・CSP・Cookie・Same-Origin Policy
問い合わせ画面の保存型XSSを一つの事例に、攻撃者の文字列がどこでJavaScriptになり、ブラウザがどの権限で動かし、CookieとCSPが何を制限するかを追います。科目Bでは、設定名を暗記するだけでなく、構成・HTTPヘッダ・アプリログ・CSP違反報告から成立条件と対処後の確認を判断します。
読み順は、①同一オリジンとCookie、②XSSの成立点、③出力とDOMの修正、④CSPの設計、⑤時系列ログ、⑥封じ込めと復旧、⑦記述演習です。portal.exampleとsupport.portal.example、時刻、識別子、HTTP応答、ログはすべて架空です。
1. 事例の主体とブラウザの信頼境界
架空の企業はhttps://portal.exampleで請求先管理と問い合わせを提供します。support.portal.exampleは別ホストのヘルプサイトです。攻撃者は一般利用者として問い合わせ本文を登録できますが、経理担当者BのセッションIDやサーバ側のテンプレートは変更できません。Bが問い合わせ一覧を開くときに何が起こるかを調べます。
攻撃者:問い合わせ本文を保存できる一般利用者。経理担当Bの権限は持たない。
Bのブラウザ:portal.exampleのHTMLを受け取り、同じオリジンのJavaScriptを実行する。
Webサーバ:問い合わせ本文をDBから読み、一覧のHTMLに入れる。CookieでBのセッションを識別する。
管理API:POST /api/payees/41で、権限のある利用者の振込先を更新する。成功時には監査ログを出す。
CSP:portal.exampleのHTML応答で配布する、ブラウザ向けの読み込み・実行制限。
次の図は、入力を保存する主体と、表示時に権限を持つ主体を分けます。攻撃者が登録した文字列がBのページで実行されると、実行場所はportal.exampleです。
攻撃者の保存した本文が、経理担当Bのブラウザで解釈されるまで。全て架空の事例。
最後のPOSTは、本文を文字列として表示すれば発生しません。図は脆弱な表示処理と後述の攻撃条件を満たした場合の流れです。リクエストの存在だけで、攻撃者がCookie値を読んだとまでは言えません。
2. Same-Origin Policyは何を比べるか
Same-Origin Policy(SOP)は、ある文書のスクリプトが別のオリジンの文書や応答を読む行為などを制限します。オリジンはURLのscheme、host、portの組です。パスはオリジン判定に入りません。通常のHTTPSの既定ポート443と明示した443は同じです。
基準: https://portal.example/inquiries
https://portal.example/api/payees/41 -> 同一オリジン
https://portal.example:443/page -> 同一オリジン
https://portal.example:8443/page -> 別オリジン
http://portal.example/page -> 別オリジン
https://support.portal.example/ -> 別オリジンSOPは別オリジンへの送信を全て禁止する規則ではありません。リンク、フォーム、画像などの送信・埋込みには許されるものがあります。一方、別オリジンの応答本文をJavaScriptで読むことは通常制限されます。CORSはサーバが特定の別オリジンからの読取りを許す仕組みで、単にリクエストを送れることと分けて考えます。
portal.exampleのHTMLに混入して実行されたスクリプトは、その文書と同じオリジンで動きます。攻撃者が管理する外部ファイルから読み込まれたJavaScriptでも、読み込んだ文書で実行されれば、その文書側の権限を使います。SOPは同一オリジン内のXSSからBのAPIを守りません。
support.portal.exampleはportal.exampleと別オリジンです。両者はCookieのSameSite判定では同じsiteになる場合があります。オリジンとsiteを混同すると、SOPが許す読取りとCookieが送られる条件を取り違えます。
例えばsupport.portal.exampleのページに細工したフォームがある場合、そのページのスクリプトはportal.exampleの応答をSOPで読めません。しかしフォーム送信自体は別の条件で可能です。同じsiteへの要求ならSameSite=StrictやLaxでもCookieが付く場合があるため、重要操作ではCSRF対策や業務上の再確認も別途設計します。この話と、portal.example内で実行されるXSSは攻撃者の位置が異なります。
portal.exampleとsupport.portal.exampleの比較。schemeful same-siteの考え方による。
図の『同じsite』はCookieを必ず共有するという意味ではありません。CookieのDomainとPath、Secureなども送信先を制限します。SameSiteが一致しても、support.portal.example上のJavaScriptがportal.exampleのDOMを読めるわけではありません。
3. Cookieは送信条件と読取り条件が異なる
この事例でBがログインすると、サーバは次のCookieを返します。`__Host-`接頭辞にはSecure、Path=/、Domain属性なしが必要です。Domainを付けないhost-only Cookieなので、support.portal.exampleへのリクエストには送信されません。
HTTP/1.1 200 OK
Set-Cookie: __Host-session=S-B7; Path=/; Secure; HttpOnly; SameSite=Lax
Content-Type: text/html; charset=utf-8Secure:HTTPS接続に限定して送る。サーバ側の認可や暗号化そのものの代わりにはならない。
HttpOnly:document.cookieなどのJavaScript APIから値を読ませない。ブラウザのHTTPリクエストでは引き続き送られる。
SameSite=Lax:異なるsiteからの多くのサブリクエストやPOSTで送信を抑える。外部siteからのトップレベルの安全なナビゲーションでは送られ得る。
Domainなし:設定したportal.exampleホストに限定する。通常のCookieにDomain=portal.exampleを付ければサブドメインにも送信されるが、この__Host-sessionにDomainを付けると対応ブラウザでは設定が拒否される。
Path=/:そのホストの各パスへ送る。Pathはアクセス制御の境界にはならない。
SameSite=Strictでも、同じsiteの別サブドメインを含む攻撃や、portal.example内で実行されたXSSを解決できません。SameSite=NoneにはSecureが必要です。属性を省略した場合のブラウザ既定値に依存せず、要件に合わせて明示します。
HttpOnlyにより、XSSから`document.cookie`でこのセッション値を読む経路は塞がれます。ただしportal.exampleで動く悪意あるスクリプトが同一オリジンのAPIを呼ぶと、通常のブラウザの資格情報付きリクエストにCookieが付くため、Bに許可された操作を実行し得ます。Cookie窃取の防止と、Bの権限を使った操作の防止は別です。
同じスクリプトは、Bの画面に表示される情報や、同一オリジンAPIから返る情報も読めます。HttpOnlyでCookie値を隠しても、閲覧可能な請求データや画面上のトークンは別途保護が必要です。情報を外部へ送れたかは、CSPの各送信経路とブラウザ・サーバの通信記録を確認します。
Cookieはオリジン単位ではなく、Domain・Pathなどの規則で送信先が決まります。同じホストでもポートの違いはCookieの送信境界になりません。SOPとCookieの境界を同一視しないことが、構成図の読解で重要です。
3-1. Cookieヘッダで見えるものと見えないもの
ブラウザは条件に合うCookieを後続のHTTP要求のCookieヘッダへ入れます。一方、サーバが受けるCookieヘッダには、Set-Cookie時のSecure、HttpOnly、SameSite、Domain、Path属性は再掲されません。監査時はレスポンスのSet-Cookie、ブラウザの保存状態、要求のCookie送信、サーバのセッション照合を別々に確認します。
// 説明用。要求側ではCookieの属性は見えない
GET /inquiries HTTP/1.1
Host: portal.example
Cookie: __Host-session=S-B7
// 応答側で属性を指定する
Set-Cookie: __Host-session=S-B7; Path=/; Secure; HttpOnly; SameSite=LaxCookie値をアクセスログへそのまま残す設計は、調査のために新たな秘密情報の複製を作ります。この教材の監査ログはCookie値の代わりにセッション参照IDを記録します。セッションIDの発行、失効、再発行、固定化攻撃は別のWeb認証記事で詳しく扱う範囲です。
4. XSSはどこで文字列が実行可能になるか
Cross-Site Scripting(XSS)は、信頼しないデータをHTMLやDOMに危険な形で入れ、閲覧者のブラウザに想定外のスクリプトを実行させる問題です。この事例の入口は問い合わせ本文、危険な処理はHTML文字列としての描画、実行主体はBのブラウザです。攻撃者はサーバのプログラムを直接書き換える必要はありません。
4-1. 保存型・反射型・DOM型を入力源と実行点で分ける
保存型:入力をDBなどに保存し、別の利用者がページを開いたときに危険なHTMLとして返す。この事例が該当する。
反射型:検索語などリクエスト由来の値を、その応答へ危険な形で埋め込む。攻撃者が細工したURLへ誘導する例がある。
DOM型:ブラウザのコードがlocation.hashなどを読み、innerHTML等の危険なDOM APIへ渡す。サーバのアクセスログに攻撃文字列が現れない場合がある。
三つは完全に排他的な分類ではありません。保存されたデータをクライアント側のinnerHTMLに入れる構成なら、保存された入力とDOM上の危険な処理が重なります。試験では名称だけでなく、データの入口、途中の保存、最終的な実行点を示します。
4-1a. 反射型とDOM型を短い例で追う
反射型: GET /search?q=<入力>
サーバがqを検索結果見出しへHTMLとして挿入
応答HTMLを開いたブラウザで実行され得る
DOM型: /help#<入力>
location.hash -> innerHTML
URLの#以降は通常HTTP要求に送られない反射型では、攻撃者が作ったURLとサーバの応答HTMLを照合します。DOM型では、フラグメントが通常サーバへ送られないため、アクセスログのURLだけでは入力を再現できないことがあります。ブラウザでのDOM変化、配信済みJavaScript、利用者が開いた完全なURLを調べます。
4-2. この事例の脆弱な表示と攻撃の成立条件
サーバは問い合わせ本文をHTMLエスケープせず、一覧テンプレートへ連結していました。登録フォームは文字数だけ検査し、HTMLとして解釈される文字をそのまま保存します。文字数検査はXSS防止の代わりになりません。
// 脆弱な表示処理の概念例
html += '<div class="message">' + inquiry.body + '</div>';
// 攻撃者が登録した本文の概念例(実行内容は省略)
<img src="x" onerror="/* 同一オリジンAPIを呼ぶ処理 */">ブラウザはimgの読み込み失敗時にonerrorのコードを実行します。攻撃者は問い合わせの登録権限とBに閲覧させる機会が必要です。CSPがそのインラインイベントハンドラを実際にブロックするなら、この例のスクリプトは実行されません。
この事例では、Bが振込先を変更できる権限を持ち、画面上のCSRFトークンを正規スクリプトが読める配置にしています。もし悪意あるコードが実行されれば同じ値を読んでAPI要求へ付けられるため、CSRF検査も通り得ます。API側がBに権限を認めた結果は、攻撃者本人がその権限を持つことを意味しません。
- 1. 本文の登録:証跡 登録者ID・本文ID・保存時刻/防御・対処 入力源と編集権限を記録する
- 2. 一覧への描画:証跡 応答HTMLと描画処理/防御・対処 文脈に合う出力エスケープ
- 3. ブラウザで実行:証跡 CSP報告とブラウザ観測/防御・対処 有効なCSPで実行を制限
- 4. Bの権限で操作:証跡 APIと監査ログ/防御・対処 不審な変更を保留・確認
入力権限、HTML解釈、Bの権限による操作を一続きで示す。
図の防御は別々の位置に作用します。登録時の入力検査だけでは安全な描画にならず、CSP報告だけでは実行を止めません。API側ではBに権限があるため、通常の認可検査が成功し得ます。
5. 出力文脈に合わせて修正する
原因の修正は、利用者入力をコードではなくデータとして扱うことです。最も単純な本文表示はテキストノードとして挿入します。サーバ側テンプレートもHTML本文に対する自動エスケープを維持します。エスケープ後の文字列を再びinnerHTMLへ渡すと、想定した安全性が崩れ得ます。
// 本文を文字として表示する安全側の例
messageElement.textContent = inquiry.body;
// 危険:HTML構文として解釈する
messageElement.innerHTML = inquiry.body;出力先が異なれば防御も変わります。HTML本文ではHTMLエスケープ、引用符付き属性では属性文脈へのエスケープと属性名の固定、URLでは許可するschemeと遷移先の検査が必要です。JavaScriptやイベントハンドラのコード中へ利用者入力を直接埋め込む設計は避けます。
HTML本文:`<`や`&`などをデータとして表示する。フレームワークの自動エスケープを解除しない。
属性値:属性名を固定し、値を引用符で囲む。`onclick`のような実行属性へ入力を入れない。
URL:`href`の値は許可したschemeを検査する。HTMLエスケープだけでは`javascript:`の意味を消せない。
DOM:文字ならtextContentを使う。innerHTML、insertAdjacentHTML、document.writeなどへ未信頼値を直接渡さない。
利用者にHTML編集を許す場合:信頼できるサニタイザで許可要素・属性を限定し、後段で未検査のHTMLを足さない。更新と回帰試験も行う。
例えば検索語を`<span>`の中へ出す修正と、リンク先の`href`へ入れる修正は同じではありません。単に入力から`<script>`を削除しても、イベント属性や危険なURL、DOM操作経由の経路が残ります。サーバ側・クライアント側の全ての描画箇所を洗い出します。
JSONとして返すAPIでも、そのJSONをブラウザ側がinnerHTMLへ渡せばXSSは成立します。逆にDBへ危険に見える文字列が保存されただけでは、まだブラウザで実行されたとは言えません。調査では保存値、応答への入れ方、DOMへの代入方法、実際のブラウザ解釈を順に確認します。
CSRFトークンやOrigin検査は、外部siteからのリクエストを見分ける助けになります。しかし同一オリジンで実行されたXSSは画面上のトークンを読め、同一オリジンから送信できます。今回の根本原因をCSRF対策だけで修正したと判断しません。
ブラウザ内の危険なDOM APIを絞る補助策としてTrusted Typesを使う構成もあります。対応ブラウザでは、ポリシーが認めた値以外をinnerHTMLなどの対象へ渡しにくくできます。ただしポリシー自身が未信頼HTMLを通したり、未対応ブラウザの処理を放置したりすれば十分ではありません。本文の安全な描画と併せて評価します。
6. CSPはブラウザで実行経路を制限する
Content Security Policy(CSP)はHTTP応答ヘッダで配布するブラウザの制限です。script-srcはスクリプトの読み込み・実行、connect-srcはfetch等の接続、img-srcは画像、form-actionはフォーム送信、base-uriはbase要素、frame-ancestorsは埋込み元に作用します。各ディレクティブの作用点を取り違えないようにします。
6-1. nonceを使った実効ポリシーの例
次はportal.exampleが画面ごとに予測困難なnonceを生成し、同じ値を許可したscript要素と応答ヘッダへ入れる設計例です。`ABC123example`は説明用の値で、固定値として運用しません。実際の配信では十分な乱数で毎応答新しく生成します。
Content-Security-Policy:
default-src 'none';
script-src 'nonce-ABC123example';
style-src 'self'; img-src 'self';
connect-src 'self'; form-action 'self';
base-uri 'none'; object-src 'none';
frame-ancestors 'none'
<script nonce="ABC123example" src="/assets/app.js"></script>この方針なら、nonceのないonerrorイベント属性やスクリプトは実行されません。`script-src 'self'`だけでは同一オリジン上の攻撃者が制御できるJavaScriptを読み込む余地が残るため、配信ファイルとアップロード領域の分離も考えます。`'unsafe-inline'`で全インラインコードを許す設定は避けます。
`'unsafe-inline'`を単独で指定すると、インラインスクリプトを広く許可します。別の指定である`'unsafe-eval'`をscript-srcに加えると、eval()、Function()、文字列を渡すsetTimeout()など、文字列からコードを実行する処理も許可されます。この例の方針には含めず、必要だと言われた場合は呼出し元を調査します。
nonceは、許可されたスクリプトがXSSで悪用される場合や、許可したスクリプト自体が改ざんされた場合まで安全を保証しません。CSPは出力エスケープの代わりではなく、実行経路を減らす追加の制御です。攻撃者が既に同一オリジンのコードを動かせれば、`connect-src 'self'`も同一オリジンAPIへの操作は止めません。
固定されたインラインスクリプトにはハッシュを許可条件にする方式もあります。内容が変わるたびに値の再計算が必要です。`'strict-dynamic'`をnonceやハッシュと組み合わせると、許可済みスクリプトが動的に読み込むスクリプトにも信頼を広げます。対応ブラウザでは、同じscript-srcに併記した`'self'`やホストの許可リストは無視されます。
したがって、ホストが許可リストにあるという理由だけでスクリプトが動くとは判断できません。また、許可済みコードが攻撃者の入力からscript要素を組み立てるなら、動的に読み込まれるコードの来歴も調べます。
`connect-src`を狭くしても、外部への全ての流出経路を遮断したとは言えません。画像、フォーム、ナビゲーションなどは別の規則で制御されます。ポリシーの各ディレクティブと実際の通信を対応付けて判断します。
6-1a. ヘッダとディレクティブを読む順序
まず応答がContent-Security-PolicyかContent-Security-Policy-Report-Onlyかを確認し、強制と観測を分ける。
次に違反対象を特定する。インラインイベント属性、外部スクリプト、fetch、画像、フォームでは適用される指示が異なる。
script-src-attrが指定されなければ、イベント属性の判定はscript-srcなどへフォールバックする。nonceは一般のonerror属性を許可する仕組みではない。
default-srcは全ての指示の代わりではない。form-action、base-uri、frame-ancestorsなどは必要に応じて明示する。
ブラウザがポリシーを受けたページと実際の操作先を区別する。CSPはAPIサーバの認可判定を置き換えない。
例えば`connect-src 'none'`ならfetchによる送信を制限できますが、インラインの実行許可はscript-src側で判断します。`form-action 'self'`なら外部へのフォーム送信は制限できますが、同一オリジンの振込先APIへの送信は許されます。どの指示がどの行動を止めるかを、通信ログと対応させます。
6-2. Report-Onlyと強制適用を区別する
Content-Security-Policy-Report-Onlyは違反を報告する観測用ヘッダで、対象の実行を止めません。既存画面への導入時には正規スクリプトの違反を調べ、修正してからContent-Security-Policyへ移します。CSP報告は端末設定やブラウザで欠落し得るため、報告がないことだけで攻撃がなかったとは断定できません。
Content-Security-Policy-Report-Only:
default-src 'none'; script-src 'nonce-N-PREVIEW';
connect-src 'self'; report-uri /csp-reports
report: effective-directive=script-src-attr
disposition=report blocked-uri=inline
document-uri=https://portal.example/inquiriesこの報告の`disposition=report`は、違反を観測したが強制ブロックしていないことを示します。`blocked-uri=inline`はインラインコードが方針に反したという情報で、攻撃者の意図やAPI操作の結果までは示しません。実際のブラウザ・サーバログと突き合わせます。
CSPを強制に切り替える前に、ページごとの正規スクリプト、外部サービス、アップロード機能を棚卸しします。例外として広い`https:`や`unsafe-inline`を追加すると制限範囲が弱まります。変更は検証環境と段階配信で確認し、誤遮断時は必要な機能と違反箇所を特定して狭く直します。
7. ログから成立した事実と未確認事項を分ける
次は全て説明用の架空ログです。時刻はUTC。実製品に必ず同名フィールドが出るわけではありません。登録者、応答ヘッダ、CSP報告、API監査ログをrequest_idと本文IDで結びます。Cookie値と問い合わせ全文は通常ログへ残さない前提です。
10:00 app inquiry_create id=Q-91 actor=A-7
body_hash_ref=H-91 review_state=unreviewed
10:07 web GET /inquiries viewer=B-41
response=200 request_id=R-81 csp_mode=report-only
rendered_ids=[Q-91] session_ref=SB-7
10:07 csp-report document=/inquiries
effective_directive=script-src-attr
blocked_uri=inline disposition=report
request_id=R-81
10:07 api POST /api/payees/41 actor=B-41
request_id=R-82 origin=https://portal.example
session_ref=SB-7 csrf_check=pass authz=pass
result=200 audit_event=payee_changedQ-91がBの一覧に表示され、同じ時間帯にインラインコードのCSP違反報告と振込先変更が記録されています。Report-Onlyは実行を止めません。Bのセッションで権限確認とCSRF確認に成功し、変更が成立したことはAPI監査ログから言えます。
このログだけでは、onerrorが実際にR-82を発行したか、B本人が操作したか、Cookie値が外部へ流れたかを確定できません。Q-91の保存本文と実際の応答HTML、ブラウザ側の再現、R-82のリクエスト内容、Bの操作記録を照合します。`HttpOnly`の設定からCookie値の直接読取り経路は抑えられますが、他の情報流出まで否定できません。
7-1. 正常例と強制CSP後の差分
正常: Q-92 body='<img ...>'
rendered_as_text=true script_executed=false
描画修正試験: Q-91 rendered_as_text=true
inline_handler_created=false
no_unexpected_payee_change_in_test=true
CSP単独試験: isolated_page=inline-handler-check
csp_mode=enforce inline_handler=blocked
handler_executed=false描画修正試験ではQ-91を文字として表示するため、イベントハンドラは生成されません。CSP単独試験では、検証環境の専用ページに確認用のインラインイベント属性を置き、同じ強制ポリシーが実行を止めることを確認します。『CSP報告が消えた』だけでは、単に報告設定が外れた可能性もあるため十分ではありません。
8. 封じ込め、原因修正、再開判断
脆弱な問い合わせ本文が残っていれば、別の閲覧者にも被害が広がります。担当者は表示を一時停止するか安全なテキスト表示へ切り替え、問題の本文IDと登録者・閲覧者・対象API操作を調べます。証拠の本文と応答を安全に保全し、管理画面で再表示して再発させないようにします。
- 1. 表示を止める:対応 問題本文の表示停止と暫定隔離/確認する証跡 対象本文ID・公開範囲
- 2. 影響を調べる:対応 閲覧者と変更操作を突合/確認する証跡 アクセス・CSP・API監査
- 3. 描画を修正:対応 安全な出力とCSP強制を実装/確認する証跡 差分・回帰試験
- 4. 安全に再開:対応 不正変更を是正して段階公開/確認する証跡 再現試験・監視結果
表示経路を止め、影響を調査し、描画修正とCSPを確認して再開する。
振込先変更が確認された場合は業務担当と連携して変更を保留・差戻し、後続処理への影響を調査します。セッション値の流出が疑われる証拠があれば対象セッションを失効し再認証させます。今回のログだけで全利用者のセッション窃取を断定しません。
本文が通る全経路を調べる。HTML応答、一覧のクライアント描画、通知メール、管理画面も対象にする。
描画を文脈に応じて修正する。文字はテキストとして表示し、必要なHTMLだけをサニタイズする。
CSPをReport-Onlyから強制へ移す。正規のスクリプトにnonceを付け、例外を最小限にする。
保存型、反射型、DOM型の代表入力で回帰試験し、Cookie属性・API監査・CSP報告も確認する。
被害を受けた設定変更を是正し、画面とAPIの監視を続けながら公開範囲を戻す。
復旧の判断は、攻撃文字列がコードとして解釈されず、正規機能が動き、想定外のAPI操作が再現しないという証拠で行います。CSPだけ変更してDB中の危険な表示経路を放置したり、本文を削除するだけで脆弱なテンプレートを残したりしません。
9. 科目B(午後)の記述演習
各問では成立条件、ログから確認できる事実、追加で必要な証拠、対策の適用位置を分けて答えてください。設定名だけではなく、なぜその条件で効くかを述べます。
演習1:保存型XSSの成立点
条件:A-7が本文を登録し、B-41が一覧を開いた直後、`script-src-attr`のReport-Only報告が出た。問い:入力から実行までの成立条件を答える。
解答:A-7に登録権限があり、本文がB-41へ表示され、表示処理が本文をHTMLとして解釈し、CSPが強制ではなかった場合に実行し得ます。保存本文、応答HTML、ブラウザ動作で確認します。
誤答の理由:『報告があるのでCSPが阻止した』はReport-Onlyを強制適用と混同しています。
演習2:HttpOnlyとAPI操作
条件:`__Host-session`はHttpOnlyで、B-41のAPI変更ログにはsession_ref=SB-7とある。問い:Cookie窃取とAPI操作について何が言えるか。
解答:JavaScriptからCookie値を直接読む経路は抑えられます。しかし同一オリジンのスクリプトがAPIを呼べば、ブラウザはCookieを送れます。変更ログは操作成立を示し、Cookie値の窃取までは示しません。
誤答の理由:『HttpOnlyならXSSは無害』は値の読取りと、権限を使うリクエストを混同しています。
演習3:SOPとサブドメイン
条件:画面はhttps://portal.example、ヘルプはhttps://support.portal.exampleで動く。問い:同一オリジンか、SameSiteとの違いを答える。
解答:hostが異なるので別オリジンです。schemeful same-siteでは同じsiteとして扱われ得ますが、SOPによるDOM・応答の読取りは許されません。Cookie送信はDomainなどの属性も必要です。
誤答の理由:『同じ親ドメインなので相互のDOMが読める』はオリジンとsiteを混同しています。
演習4:CSPの適用状態
条件:`Content-Security-Policy-Report-Only`の`disposition=report`と、直後のAPI変更成功を確認した。問い:CSPに関する原因と優先する修正を答える。
解答:報告専用ポリシーは実行を止めません。本文の安全な描画を修正し、正規スクリプトを確認してCSPを強制適用します。API監査とブラウザ再現で影響を確かめます。
誤答の理由:『CSP報告が出たから根本原因は修正済み』は観測と遮断を混同しています。
演習5:出力文脈
条件:問い合わせ本文はHTML本文とリンクのhrefの二か所へ入る。開発者は両方へHTMLエスケープだけを適用した。問い:残る問題と修正を答える。
解答:HTML本文はテキスト表示でよい一方、hrefには許可するURL schemeと遷移先の確認が必要です。属性値も引用符で囲み、属性文脈に合わせて扱います。
誤答の理由:『`<script>`さえ消せばよい』では、イベント属性や危険なURLなどを見落とします。
演習6:ログからの断定範囲
条件:Q-91表示、CSP違反報告、B-41の振込先変更が同時刻に記録された。問い:確定できる事実と追加証拠を答える。
解答:本文の表示、方針違反の検出、Bのセッションでの変更成立は言えます。XSSが変更を起こした因果関係は、保存本文、応答HTML、R-82の内容、ブラウザ再現と操作記録で検証します。
誤答の理由:『同時刻だからCookieが窃取された』は流出を示す証拠がありません。
演習7:修正後の再開条件
条件:問題の本文を削除したが、一覧の描画コードは変えていない。問い:再開前に必要な対応を答える。
解答:描画処理を安全なテキスト表示または適切なサニタイズへ修正し、同種の入力で回帰試験します。CSP強制と正規機能を確認し、不正な設定変更を調査・是正してから段階的に再開します。
誤答の理由:『本文を一件消したので再発しない』は同じ入口からの再登録を防げません。
演習8:SameSiteとXSS
条件:セッションCookieはSameSite=Strictで、portal.example自身のページでXSSが実行された。問い:API操作をCookie属性で止められるか。
解答:SameSite=Strictは異なるsiteからのCookie送信を制限します。同一site・同一オリジンで動くXSSからのAPI要求は、この属性だけでは止まりません。表示処理とCSP、重要操作の監査を確認します。
誤答の理由:『Strictなら全ての不正操作を防ぐ』はCookieの送信条件を、スクリプトの実行制御と取り違えています。
10. 仕様・実装ガイド
W3C:Content Security Policy Level 3
OWASP:Cross Site Scripting Prevention Cheat Sheet
この記事についてAIに深掘り質問する
ChatGPT、Claude、Perplexityにこの記事を参照させ、要点の確認や疑問点を自由に質問できます。
次におすすめの学習
編集・検証について
編集・検証:IT資格ラボ編集部
IPAが公開する試験要綱・シラバス・過去問題と、各技術の公式資料を優先して内容を確認しています。制度変更や誤りを確認した場合は、記事を見直して更新します。
編集方針・情報源・訂正方針を見る