要約

  • W3Cが2011年11月29日に公開したCSP最初の作業草案は、資源をどこから読み込むかサイトが宣言し、ブラウザーが照合する仕組みを示した。
  • 2016年12月15日のLevel 2勧告は、強制する方針と報告だけを受ける方針、特定のインラインスクリプトを許すnonceやハッシュを定めた。招待状を書くのはサイト、入口に立つのはブラウザーだ。

サイトはパーティーを開き、招待状の控えをなくしていた。昔からの提供元のスクリプトが来る。誰も担当者を覚えていない古い部品のスクリプトも来る。画像と書体が並び、その後ろに通信先が続く。紛れ込んだコードまで昔なじみの顔をして入ろうとする。用心棒を雇うのは簡単だ。難しいのは、主人が渡せる客名簿を持っているかどうかだった。

W3Cが2011年11月29日に出したContent Security Policyの最初の公開作業草案は、役割をはっきり分けた。草案は、サイトが資源の読み込み元を制限する宣言的な方針を記し、クロスサイトスクリプティングを含む内容注入への対策を意図した。サイトが許す出所を述べる。ブラウザーはページが実際に資源を求めたとき、その規則に照らして通すか決める。

名簿は「信用できる」という一枚の札ではない。初期草案には基準となるdefault-srcのほか、script-src、img-src、style-src、font-src、connect-srcなどが並ぶ。写真を受け取る場所と、動くコードを受け取る場所を別にできる。額に入った風景画と舞台の照明卓を動かす人に、同じ合鍵を渡す必要はない。資源の仕事ごとに入口を分ける発想だった。

その仕組みはサイトの内情も映し出した。運営者は使うつもりの提供元を知り、ブラウザーは実際に飛ぶ要求を見る。CSPは両者を結んだ。script-srcを書くのは速い。数年前の特設ページが今も古い外部部品に頼っているかを調べるのは、少々骨が折れる。名簿が短すぎれば、怪しいコードと一緒に正規の決済処理まで止めてしまう。入口の係が融通を利かせないのではない。主人が招待客を把握していなかったのだ。

2016年12月15日のW3C Content Security Policy Level 2勧告は、開場前の予行演習を用意した。Content-Security-Policy-Report-Onlyという応答ヘッダーなら、ブラウザーは方針に反した要求を記録して報告し、資源の読み込みは続ける。勧告の例も、この方法で方針を育ててから、実際に止めるContent-Security-Policyヘッダーへ移る流れを示す。用心棒はまず手帳を持って客を眺め、次の当番からロープを引く。

報告に書かれたものが、すべて悪者というわけではない。想定外の書体サービス、長く放置された解析用の通信、移転した部品の住所かもしれない。ブラウザーが知らせるのは、ページで起きた要求だ。サイトの側が、その依存関係を使うべきか、ページから外すべきか、方針を直すべきかを決める。報告専用モードが教えるのは、運営者の頭の中にある整ったサイトと、実際に動いているサイトの差である。

名簿の置き場にも意味があった。2016年勧告はHTTP応答ヘッダーを優先し、HTMLの早い位置に置くmeta要素も認めた。ただしmetaより前に読み込まれた資源には効かず、報告専用モードも表せない。客が入場した後で掲示板を立てても、入口での照合には間に合わない。応答ヘッダーなら、ページの読み込みが始まるところでブラウザーが受け取れる。

ページ内に直接書かれたスクリプトは、特にやっかいな客だった。正規の用途で必要なこともある。一方、ページ内のコードを何でも許せば、注入されたコードも肩を並べる。Level 2はnonceとハッシュによって、狙ったスクリプトを識別する方法を記した。応答ごとに作る乱数を方針と許可した要素に合わせる。あるいは内容そのもののハッシュを使う。JavaScriptと書かれた紙を持つ全員を通す代わりに、特定の客へ招待状を出せる。

他の入口もある。img-srcは画像、connect-srcは一定の通信、base-uriは相対リンクの基準、form-actionはフォームの送り先、frame-ancestorsはそのサイトを枠に入れてよいページを扱う。画像とスクリプトを一つの雑な「許可ドメイン」欄へ押し込めず、行動ごとに規則を決める。サイトが意図を記し、ブラウザーがその瞬間の要求を判断する。

W3Cが残したCSP Level 2の刊行履歴には、草案を経て2016年12月の勧告に至る道筋がある。日付は仕様書の節目だ。この経緯で定着した分担はもっと身近で、少し気まずい。サイトは使いたい資源の出所を言葉にし、ブラウザーが読み込みを見張り、報告が「思っていたサイト」と「本当に動いているサイト」の違いを示す。

読者は記事や買い物ページを開く前にscript-srcを読むわけではない。ページが動くか、何かが突然消えるかを感じる。CSPは舞台裏の名簿である。用心棒は招待のないコードを止められる。主人はその前に、自分の宴会の客を数えなければならない。ウェブの安全対策が、まず点呼から始まるとは気の毒な話だ。