この記事をシェアする

ブログにContent Security Policyを設定してみようかと思う

Content Security Policyとは

まあ、ワシのようなモグリの闇セキスペの言うことよりMozillaの言うこと聞いた方が良いと思う

サーバがブラウザに返すレスポンスヘッダの一つ。
ヘッダ内には「このサイトでは○○ってドメインから配信されたJSだけ許可するよ。画像は××ってドメインから配信された奴だけ許可するよ。インラインのJSは許可しないよ」みたいな情報がリスト形式で記載されている。
ヘッダを受け取ったブラウザはそのリストに従い、○○以外から配信されたJavaScriptや××以外から配信された画像をブロックする。

結果、第三者が(例えば投稿フォームを利用して)サイト内にスクリプトを埋め込んだとしてもブラウザでブロックされて実行されなくなる→XSSが未成立になるって寸法。
第三者がコンテンツ埋め込む余地がない&埋め込んだとしても適切にエスケープしているのであれば不要では? とも思うけど、人間が作るものである以上どこかに穴がある可能性は拭えない。保険的対策としては十分すぎるくらい有用だろう。
規模の大きい・昔から運用しているサイトの場合、利用している外部コンテンツの数がメチャクチャ多い→導入にあたって慎重に設定内容を検討したりサイトの改修をしないといけなかったりで、保険にしては導入コストが馬鹿にならないと思うが。

あとはまあ、よしんばサイトに穴がなかったとしても、ブラウザ拡張機能によってスクリプトを埋められる可能性はあるので、とりあえず設定しておけば何かしら意味はあるんでないかと思う。

とりあえずこんな感じで設定してみる

// CSPヘッダを出力する
function csp_header () {
    global $pagenow;
    // 管理画面だったら何もしない
    if (is_admin()) {
        return;
    }
    // ログイン画面へのアクセスだった場合も何もしない
    if ($pagenow === 'wp-login.php') {
        return;
    }
    // とりあえず何でもかんでも許可する
    $csp = "Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval';";
    // レポートの方は渋めに。report-uriはサンプル
    $csp_report = "Content-Security-Policy-Report-Only: default-src 'self'; report-uri https://hoge.example.com";
    
    header($csp);
    header($csp_report);
}
// HTTPヘッダを出力する際に使うアクションフック
add_action( 'send_headers', 'csp_header' );

Content-Security-Policy-Report-Only ってのは、CSPのテスト用に使うヘッダで、ポリシ違反のコンテンツがあってもブロックはせず、レポートを表示するだけに留めてくれるってもの。
このレポートを参考にして、そのサイトに必要な設定を検討していくってわけ。

report-uriでURLを指定すると、そのURLに向けレポートがJSONでPOSTされる。
JSONをパースしてDBにぶっこむ仕掛けなりなんなりを作っておけば、一体何が引っかかってるのか調査するのに役立つだろう。
そういうのをやってくれるサービスもあるので、大人しく利用した方が無難かもしれない。

https://report-uri.com/

1月10,000レポートまで無料アカウントの枠内で処理してくれるようだ。

んなわけで。実際にヘッダを設定したあとのサイトの様子を見てみましょうか。

じゃんっ!

とんでもねぇことになっちまった。

これをどうやっていい感じに調整していくのか。
この話に次はあるのか。

乞うご期待。

この記事をシェアする