結論(CSPの基幹ディレクティブ)
CSPの基幹ディレクティブとは、XSSなどの被害を抑えるうえで重要な object-src・base-uri・form-action・frame-ancestors の4つを指します。base-uri・form-action・frame-ancestors は default-src で代用されず、object-src も明示が推奨されるため、default-srcを厳しくしても抜けが生じます。推奨の最小構成は object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self' です。
この記事のポイント
- base-uri・form-action・frame-ancestors はfetchディレクティブではないため、default-srcを厳しくしても制限されません。
- object-src は default-src で代用されますが、OWASP ASVSやStrict CSPでは object-src 'none' の明示が求められます。
- 'none' は単独で書いたときだけ有効で、object-src 'none' https: のように並べると https の任意オリジンを許可してしまいます。
- 複数のCSPヘッダーがある場合、4つはどれか1つのポリシーに含まれていれば効果があります。
- セキュリティAIチェッカーは強制CSPヘッダーで4つすべて合格なら○、1つでも不足・弱ければ△(重み3)と判定します。
| 診断項目名 | CSPの基幹ディレクティブ |
|---|---|
| 項目ID | headers.csp-directives |
| 分類 | コンテンツセキュリティポリシー(CSP) |
| 重大度・配点の重み | 重要(high) 重み 3 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V3.4.3(Level 2「最低限、object-src 'none' と base-uri 'none' を含むグローバルポリシーを使い、許可リストまたは nonce/hash を定義すること」)、OWASP ASVS 5.0.0 V3.4.6(Level 2「すべての応答で frame-ancestors ディレクティブを使い、既定で埋め込みを禁止すること」)、OWASP WSTG-CONF-12(object-src、base-uri、frame-ancestors の不足を確認)、W3C Content Security Policy Level 3(ディレクティブのフォールバック、複数ポリシー)、CWE-79(XSS)、CWE-1021(クリックジャッキング) |
CSPの基幹ディレクティブとは
CSPの基幹ディレクティブとは、Content Security Policy(CSP)のうち、XSSやHTMLインジェクションの被害を抑えるうえで特に重要な object-src・base-uri・form-action・frame-ancestors の4つのディレクティブを指します。
CSPの多くのディレクティブ(script-src、img-src など)は、指定がなければ default-src の値で代用されます。しかし、この4つは default-src で代用されないか、代用に頼ると抜けが生じやすいものです。
| ディレクティブ | 制限する対象 | default-srcでの代用 |
|---|---|---|
object-src | <object>/<embed> によるプラグイン読み込み | される(ただし明示が推奨) |
base-uri | <base href> による相対URLの基準 | されない |
form-action | フォームの送信先 | されない |
frame-ancestors | 自ページを埋め込める親ページ | されない |
セキュリティAIチェッカーはこの項目で、強制CSPヘッダーにこれら4つが適切に含まれているかを確認します。CSPが強制モードで届いているかは「CSPがレスポンスヘッダーで強制されている」、default-src そのものは「CSPのdefault-src」で別に評価します。
推奨する最小構成
Content-Security-Policy: object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'
既存のCSPにこの4つを追加するだけで、多くのサイトでは表示に影響しません。
4つの基幹ディレクティブはそれぞれ何を防ぐのか
object-src 'none'
Flash等のプラグインは主要ブラウザで廃止されていますが、<object>/<embed> は依然として script-src の制限を回避する経路になり得ます。Strict CSP(OWASP CSP Cheat Sheet、ASVS)では object-src 'none' が必須要素です。
base-uri 'none' または 'self'
攻撃者がHTMLインジェクションで <base href="https://attacker.example/"> を挿入すると、ページ内の相対パスで書かれたスクリプト(<script src="/js/app.js">)が攻撃者のサーバーから読み込まれます。nonce付きスクリプトでも相対URLなら乗っ取られるため、nonceベースのCSPでも必須です。ASVSの最低要件は 'none' ですが、<base> 要素を正当に使うサイトでは 'self' が現実的な選択です。
form-action
XSSやHTMLインジェクションで挿入された偽フォーム、または既存フォームの action の書き換えにより、入力内容(ログイン情報、申請内容)が外部へ送信されるのを防ぎます。
frame-ancestors
クリックジャッキング対策です。X-Frame-Options の後継で、複数オリジンの許可など、より柔軟に指定できます。meta要素では使えないため、ヘッダーで送る必要があります。全ページへの適用状況は「CSP frame-ancestorsを全HTMLへ適用」で確認します。
default-srcだけでは足りない理由(フォールバックの仕様)
directive fallback list
W3C CSP Level 3 の「directive fallback list」では、object-src が無い場合は default-src が使われます。そのため default-src 'none' を指定し object-src を書いていないポリシーは、実効的に object-src 'none' と同じです。
一方、base-uri・form-action・frame-ancestors は fetch ディレクティブではないため、default-src を厳しくしても制限されません。これが「default-srcを書いたから大丈夫」という誤解が生まれる原因です。
'none' と他の値の混在
CSPの source list で 'none' は「他に何も書かれていない」ときだけ意味を持ちます。object-src 'none' https: のように並べると、ブラウザは 'none' を無視し、https の任意のオリジンを許可してしまいます。'none' は単独で書く必要があります。
複数ポリシーの扱い
Content-Security-Policy ヘッダーが複数ある場合(HTTP上はカンマ区切りで連結されます)、ブラウザはすべてを同時に適用し、どれか1つが禁止すれば禁止されます。したがって、4つのディレクティブはどれか1つのポリシーに含まれていれば効果があります。CSPの構文上、ディレクティブの値にカンマは含められないため、カンマはポリシーの区切りとして扱えます。
CSPの基幹ディレクティブの診断基準(セキュリティAIチェッカー)
取得方法
- トップページ(リダイレクト追跡後の最終応答)の
Content-Security-Policyレスポンスヘッダーだけを対象にします。 - Report-Onlyヘッダーとmeta要素は対象外です(Report-Onlyは強制されず、metaでは frame-ancestors が無効なため)。
- ヘッダー値をカンマで個々のポリシーに分け、ディレクティブ名は大文字小文字を区別せずに照合します。
各ディレクティブの合格条件
| ディレクティブ | 合格条件(いずれかのポリシーで満たせばよい) |
|---|---|
| object-src | object-src 'none' が単独で指定されている。または、そのポリシーに object-src がなく default-src 'none' が単独で指定されている |
| base-uri | base-uri 'none' または base-uri 'self' が単独で指定されている |
| form-action | form-action に何らかの値が指定されている |
| frame-ancestors | frame-ancestors に何らかの値が指定されている |
判定条件
| 判定 | 条件 | 根拠文の例 |
|---|---|---|
| 対象外(na) | 強制CSPヘッダーがない(meta/Report-Onlyのみを含む) | 強制CSPがないため対象外です。 |
| ○ 問題なし(pass) | 4つすべて合格 | object-src、base-uri、form-action、frame-ancestorsを確認しました。 |
| △ 要確認(warn) | 1つ以上が不足または弱い | 不足または弱いディレクティブ: base-uri、form-action |
form-action と frame-ancestors は値の厳しさまでは評価しません(frame-ancestors * でも合格扱い)。値の妥当性は手動で確認してください。
得点への影響
| 判定 | 得点 |
|---|---|
| ○ 問題なし(pass) | 3点(重み3) |
| △ 要確認(warn) | 1.35点 |
| 対象外(na) | 採点から除外 |
自治体サイトでの判定例
| CSPヘッダーの内容 | 判定 |
|---|---|
frame-ancestors 'self'; upgrade-insecure-requests のみ | △(object-src、base-uri、form-action が不足) |
default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'none' | ○(object-src は default-src 'none' で代用) |
default-src 'self'; object-src 'none' https:; ... | △('none' が他の値と混在し無効) |
2本のヘッダー「default-src 'self'; object-src 'none'; base-uri 'self'」と「form-action 'self'; frame-ancestors 'self'」 | ○ |
基幹ディレクティブが不足するとどんなリスクがあるか
- base-uri 欠落:HTMLインジェクション1か所で、サイト全体のスクリプト読み込み先を差し替えられ、CSPがあってもXSSと同等の被害になります(CWE-79)。
- form-action 欠落:住民が入力した申請内容・問い合わせ内容・パスワードが、挿入された偽フォームや書き換えられた action で外部へ送信されます。
- frame-ancestors 欠落:X-Frame-Options も無い場合、クリックジャッキングが可能になります(CWE-1021)。ASVS 5.0.0 では frame-ancestors の使用自体が要件です。
- object-src 欠落:古いプラグイン経路や
<embed>を使った制限回避の余地が残ります。
CSPの基幹ディレクティブの設定方法(Apache・nginx・IIS・Next.js)
外部の決済・電子申請サービスへフォームを送信している場合は、form-action にその送信先オリジンを追加します。自治体の他サイトや観光協会サイトから埋め込まれる必要がある場合は、frame-ancestors に許可するオリジンを列挙します。
Apache(.htaccess)
<IfModule mod_headers.c>
Header always set Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; form-action 'self' https://shinsei.example.lg.jp; frame-ancestors 'self'"
</IfModule>
nginx
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'" always;
IIS(web.config)
<customHeaders>
<add name="Content-Security-Policy" value="default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'" />
</customHeaders>
Next.js(Strict CSPの例、proxy.ts〔Next.js 15 以前は middleware.ts〕で nonce を生成)
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
const csp = [
`script-src 'nonce-${nonce}' 'strict-dynamic'`,
"object-src 'none'",
"base-uri 'none'",
"form-action 'self'",
"frame-ancestors 'none'",
].join("; ");
段階的導入
- 4つのディレクティブを Report-Only ヘッダーで先に試し、form-action の違反(外部送信先)と frame-ancestors の違反(正当な埋め込み元)を洗い出します。
- 許可先を確定させてから、強制ヘッダーへ移します。
<base>要素を使っていないことを確認できたら、base-uri を'none'に強化します(ASVSの最低要件)。
設定後の確認方法
curl -sI https://www.city.example.lg.jp/ | grep -i '^content-security-policy:' \
| tr ';' '\n' | grep -iE 'object-src|base-uri|form-action|frame-ancestors'
サイトを壊さないための注意点(ガードレール)
form-action 'self'は、外部の電子申請・決済・検索サービスへ POST/GET するフォームを止めます。サイト内のフォームの送信先を事前に一覧化してください。frame-ancestors 'none'は、自サイト内で自分のページをiframe表示する構成(地図、カレンダー、多層iframeのポータル)を壊します。まず'self'から始めます。- X-Frame-Options と frame-ancestors を併用する場合、対応ブラウザは frame-ancestors を優先します。許可内容を一致させておくと混乱を避けられます。
よくある質問(FAQ)
default-srcを設定すればbase-uriやform-actionは不要ですか?
不要ではありません。W3C CSP Level 3のフォールバックの仕組みで default-src が代わりに使われるのはfetchディレクティブだけで、base-uri・form-action・frame-ancestors は default-src を厳しくしても制限されません。個別に明示する必要があります。
base-uriは'none'と'self'のどちらにすべきですか?
ASVS 5.0.0の最低要件は 'none' です。ページ内で base 要素を正当に使っているサイトでは 'self' が現実的な選択です。base要素を使っていないことを確認できたら 'none' に強化します。
object-src 'none' https: と書くとどうなりますか?
'none' は他に何も書かれていないときだけ意味を持つため、ブラウザは 'none' を無視し、https の任意のオリジンを許可してしまいます。'none' は必ず単独で書いてください。セキュリティAIチェッカーではこの書き方を不合格として△にします。
form-action 'self' を入れるとフォームが動かなくなることはありますか?
あります。外部の電子申請・決済・検索サービスへ送信するフォームは止まります。サイト内のフォームの送信先を一覧化し、必要な外部の送信先オリジンを form-action に追加してください。
frame-ancestorsは'none'と'self'のどちらがよいですか?
まず 'self' から始めるのが安全です。'none' は自サイト内で自分のページをiframe表示する構成(地図、カレンダー、多層iframeのポータル)を壊します。他のサイトから埋め込まれる必要がある場合は、許可するオリジンを列挙します。
frame-ancestors * でも○になりますか?
セキュリティAIチェッカーは form-action と frame-ancestors の値の厳しさまでは評価しないため、frame-ancestors * でも合格扱いになります。値の妥当性は手動で確認してください。
meta要素やReport-OnlyのCSPは評価対象になりますか?
対象外です。Report-Onlyは強制されず、meta要素ではframe-ancestorsが無効なためです。強制CSPヘッダーがない場合は対象外(na)となり、「CSPがレスポンスヘッダーで強制されている」項目で評価されます。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- W3C Content Security Policy Level 3
- MDN Content-Security-Policy
- MDN CSP: object-src
- OWASP ASVS 5.0.0 V3 Web Frontend Security(V3.4.3・V3.4.6)
- OWASP WSTG-CONF-12 Test for Content Security Policy
- OWASP Content Security Policy Cheat Sheet
- web.dev「Mitigate cross-site scripting (XSS) with a strict Content Security Policy (CSP)」