@k8ordo/static

CSPを設定する

Content-Security-Policyを設定すると、コンテンツに紛れ込んだスクリプトを動かさずに済みます。このモードでは、framework()のcspにポリシーを渡すと、ビルドが各ページの<meta>に書き込みます。

このページの内容

フレームワークが署名するもの

フレームワークはポリシーを決めません。自分がHTMLに書くインラインスクリプトに署名するだけで、それを許すポリシーはアプリが書きます。

フレームワークが書くインラインスクリプトは、hydrationのためにHTMLへ埋め込むペイロードと、Reactのスクリプトです。

アプリが自分で書くインラインスクリプトも、同じようにポリシーで許します。@k8ordo/color-schemeが描画の前に色を決めるスクリプトも、その1つです。

cspオプションにポリシーを渡す

静的なファイルは誰が読んでも同じ中身なので、リクエストごとに変えるnonceは使えません。そこでビルドは、フレームワークのインラインスクリプトをハッシュで名指しします。

vite.config.ts
import { colorSchemeScriptHash } from '@k8ordo/color-scheme';
import { framework } from '@k8ordo/static';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    framework({
      csp: {
        'script-src': ["'self'", await colorSchemeScriptHash()],
        'object-src': ["'none'"],
        'base-uri': ["'none'"],
      },
    }),
  ],
});

cspには、ディレクティブごとにソースの配列を渡します。各ページの<head>の先頭に<meta http-equiv="Content-Security-Policy">が書かれ、そのページのスクリプトのハッシュが足されます。

ハッシュを足す先はscript-srcです。default-srcだけを書いたときは、そこからscript-srcを作って足します。script-src-elemを書いたときは、そちらにも足します。どれも書いていなければスクリプトは制限されないので、ハッシュも足しません。

cspを渡さなければ、ポリシーは書かれません。

アプリのインラインスクリプトを許す

アプリ自身のインラインスクリプトは、そのハッシュをポリシーに書いて許します。@k8ordo/color-schemeなら、colorSchemeScriptHash()がハッシュを返します。

ColorSchemeProviderにdefaultPreferenceを渡しているときは、colorSchemeScriptHash()にも同じ値を渡します。スクリプトの中身が変わり、ハッシュも変わるからです。

ハッシュを書いていないインラインスクリプトは、すべて拒まれます。コンテンツから紛れ込んだスクリプトが動かないのは、このためです。

cspに書けないもの

フレームワークのモジュールのスクリプトは、ファイルでは署名できないので、出どころの'self'で許されます。'strict-dynamic'があると'self'が無視されるので、それを含むポリシーは拒みます。

frame-ancestorsとreport-uri、sandboxも拒みます。<meta>に書いても効かないディレクティブなので、ホスティングのヘッダーで設定してください。

警告

落とし穴

拒むのはframework()を呼んだ時点です。the "csp" option cannot go into a page's <meta> as it is:に続けて、問題を1行ずつ挙げた例外を投げます。

k8ordo

Baselineに入った機能を、制限なく使うReactのライブラリ群。

© 2026 k8o — MIT License

組版:Noto Sans JP / M PLUS 2