SONAE KNOWLEDGE / PHP SECURITY / 06

PHPのXSS対策。HTML・URL・JavaScriptで変わる出力の境界

htmlspecialcharsを万能にせず、画面の出力先とAI生成文・投稿の扱いを整理する。

公式資料確認:2026-10-26/AIによる資料確認・執筆

公式情報には各節で出典を付けています。確認表・架空例・受入条件はSONAEの提案です。制作と資料確認にAIを使用。本人の編集確認は未了です。専門家による独立した監修は受けていません。

出力先によって、必要な処理は変わる

OWASPはHTML本文、属性、URL、JavaScriptなどの文脈ごとに対策を分けています。HTML用のエンコードだけを、スクリプトやURLの安全化へ一般化できません。PHPで画面を作る場合も、どこへデータを埋め込むかを確認します。生成AIが返した文章も、外部由来のデータとして扱う設計にします。

公式情報:OWASP:出力先ごとのXSS対策(確認 2026-10-26)

一覧から詳細、管理画面まで追う

以下はSONAEの点検案です。問い合わせ内容が一覧、詳細、返信画面、管理者向け通知に現れるなら、それぞれの出力先を確認します。受付時点で一回加工したから終わりとせず、表示する文脈へ合わせて処理する設計を選びます。通常の文字を二重変換して読めなくする不具合と、実行可能な出力を残す問題を、同じ修正で隠さないようにします。

SONAEの点検・運用提案。架空例。

同じ文章でも、出力先が変われば対策が変わる

同じ文章でも、出力先が変われば対策が変わる出力先ごとの概念上の区分です。具体的なエンコーダーは採用するテンプレートと版に合わせて選びます。01HTMLの本文文字として表示02URL・属性用途と形式も検証03スクリプトデータとの境界を維持一つの変換を全箇所へ出力先の違いを飛ばさない独立した条件を、別の証拠で確認同じ文章でも、出力先が変われば対策が変わる出力先ごとの概念上の区分です。具体的なエンコーダーは採用するテンプレートと版に合わせて選びます。01HTMLの本文文字として表示02URL・属性用途と形式も検証03スクリプトデータとの境界を維持一つの変換を全箇所へ出力先の違いを飛ばさないそれぞれの確認結果を記録
出力先ごとの概念上の区分です。具体的なエンコーダーは採用するテンプレートと版に合わせて選びます。
図の内容を文章で読む

HTMLの本文:文字として表示。URL・属性:用途と形式も検証。スクリプト:データとの境界を維持。進めない判断:一つの変換を全箇所へ/出力先の違いを飛ばさない。出力先ごとの概念上の区分です。具体的なエンコーダーは採用するテンプレートと版に合わせて選びます。

文章として表示するか、HTMLとして扱うか

架空の社内掲示板なら、本文をプレーンテキストとして表示する仕様をまず検討します。装飾を許可する業務上の理由がある場合は、保守される仕組みで許可するHTMLを絞り、その後の加工も含めて開発担当が確認します。「社内利用だから」「ログイン後だから」という理由で、投稿をそのまま管理者のブラウザーへ挿入しないようにします。

SONAEの点検・運用提案。架空例。

リンクは、文字のエンコードと行き先を別に確認

SONAEの設計例では、表示文字とリンク先を別項目にし、許可する方式と用途を決めます。AIが作った参考リンクを自動で画面へ追加する場合も、文章が自然なことを行き先の信頼性に使いません。表示のエンコードは、リンク先の正当性やアクセス権限まで保証しないからです。外部リンクを採用した根拠と確認担当も管理します。

SONAEの点検・運用提案。架空例。

防御の追加策を、主対策の代わりにしない

CSPなどの追加策を採用する場合も、危険な出力をそのまま残してよい理由にはしません。SONAEの受入案では、対象テンプレート、出力文脈、エンコードや許可処理、通常表示、拒否時の表示を一行へまとめます。通知、プレビュー、ダウンロードなど、主画面とは違う経路を忘れないようにします。

SONAEの点検・運用提案。架空例。

受入では、誰の画面に表示されるかも記録

架空の投稿者、一般利用者、管理者を分け、どの内容がどの役割に表示されるかを確認する計画を作ります。本稿では実サイトへの投稿や攻撃コードの実行をしていません。安全な別環境で期待結果を決めて試験し、同じデータが別の画面へ移る改修のときに、出力の境界を再点検する運用へつなげましょう。

SONAEの点検・運用提案。架空例。

出力先の一覧を、改修の受入へ変える

架空の問い合わせ機能では、投稿本文は文字として表示し、参考URLは検証したリンク先として扱い、管理通知には必要な項目だけを含める方針にします。レビューでは同じ値の到達先を一覧にし、本文と属性を同じ変換で扱っていないかを見ます。JavaScriptへ渡す必要がない値はテンプレートで混ぜず、表示や受渡しの機能を分ける設計を検討します。通常の記号や日本語が壊れず、管理者向けプレビューでも方針が維持されることを受入へ含めます。防御用ライブラリーを採用する場合も、版と使う文脈を記録し、導入した事実だけで試験を省きません。

SONAEの点検・運用提案。架空例。

架空環境での受入計画

以下は未実行の計画です。実測の合格記録ではありません。

本文の通常の記号
条件:文字としての投稿
期待結果:読める文字で表示
外部リンク
条件:許可方式以外の行き先
期待結果:仕様どおり拒否・非リンク化
装飾つきの投稿
条件:許可HTMLの範囲外
期待結果:許可方針に沿って処理
管理プレビュー
条件:一般画面とは別テンプレート
期待結果:同じ境界を別に確認

社内で使う確認票

SONAEの運用案・架空例。秘密の値を記入しないでください。

入力
投稿・問い合わせ・AI生成文などの出所
出力
本文・属性・URL・管理通知・プレビュー
仕様
文字表示かHTMLか・許可する内容
受入
役割・通常表示・拒否・変更時の再確認

完了前のチェック

  • 表示先ごとに文脈を分類
  • AI生成文も信頼済みHTMLにしない
  • リンク先の検証を表示の加工と分ける
  • 管理者向けの画面も対象にする

一次資料と確認範囲

資料の対象条件と掲載内容を確認して構成した記事です。顧客への接続や攻撃再現はしていません。資料の改訂を自動追従するものではありません。実施直前に公式資料と配布元の最新案内を再確認してください。