レッスン 2-8
CSP は、
読み終えたらミドルウェアで
この頁の流れ
Content Security Policy (CSP) は、
出典を確かめた日 2026年10月27日
なぜ通るのか
Web の
ところが、
エスケープの
CSP は何を伝えるか
CSP は、
| 項目 | 決めること |
|---|---|
| default-src | ほかの |
| script-src | 動かして |
| connect-src | スクリプトから |
| object-src | 古い |
| base-uri | 頁の |
| form-action | フォームを |
| frame-ancestors | この |
frame-ancestors は、
何も守らない CSP
script-src に
頁の
もう
付け方で抜ける物
CSP は
HSTS (Strict-Transport-Security、
脆いコードと直したコード
ラボの
何でも許すか、nonce で許すか
記録
Content-Security-Policy:
script-src 'self' 'unsafe-inline' *記録
Content-Security-Policy:
default-src 'self';
script-src 'nonce-{応答ごとの値}';
object-src 'none';
base-uri 'none';
form-action 'self';
frame-ancestors 'none'直したsecrets.token_urlsafe(16) のように、
アプリの経路にだけ付けるか、出口の 1 か所で付けるか
Python
def app(req):
p = req.path
if p.startswith("/static/"):
return serve_file(p)
res = render(req)
res.headers.update(SECURITY)
return resPython
def app(req):
p = req.path
if p.startswith("/static/"):
res = serve_file(p)
else:
res = render(req)
res.headers.update(SECURITY)
return res脆い方は、/static/ の
実際の
ログでの見え方と検知
経路ごとに、
記録
$ B=http://127.0.0.1:8000
$ curl -sI $B/ | grep -i content-sec
content-security-policy: default-src ...
$ curl -sI $B/static/a.html \
| grep -i content-sec
(何も出ない)下の
| 見る物 | なぜ効くか |
|---|---|
| 経路の | 頁、 |
| CSP の | 止められた |
| script-src の | 書いた |
| 固定の nonce | 応答を |
いきなり止める
直し方と、直ったことの確かめ方
自分の
- 作業用の
フォルダに、 wsgiref で 動く 小さな アプリと、 static/a.htmlを置く - 脆い
appを127.0.0.1 で 動かし、 curl の -I で トップの頁と static/a.htmlと存在しない 頁の 頭を 取り、 CSP が 付く 経路と 付かない 経路が ある ことを 確かめる - 直した
コードに 置き換え、 CSP を nonce の 形にし、 3 つの 経路すべてに 同じ ヘッダーが 付く ことを 確かめる - 頁を
2 回取り、 nonce が 毎回 変わる ことを 確かめる - 下の
試験を 足し、 脆い 分岐に 戻すと 試験が 落ちる ことも 確かめる - 終わったら、
アプリを 止め、 作業用の フォルダごと消す
Python
CSP = "Content-Security-Policy"
PATHS = ["/", "/static/a.html",
"/no-such-page"]
@pytest.mark.parametrize("path", PATHS)
def test_every_path_has_csp(path):
h = headers_for(path)
csp = h.get(CSP, "")
assert "default-src" in csp
assert "unsafe-inline" not in csp
def test_nonce_changes():
a = headers_for("/")
b = headers_for("/")
assert a[CSP] != b[CSP]headers_for は、
本番に
関わる事例
英国の
ICO の
確認クイズ
1 問目
ミドルウェアで/static/ の
答えだと思う選択肢を押すと、その場で正誤と理由が開きます。
答え イ
同じ
2 問目
頁の
答えだと思う選択肢を押すと、その場で正誤と理由が開きます。
答え イ
unsafe-inline は、
説明課題
次の
- ミドルウェアで
付けた ヘッダーが、 静的な 配信で 抜ける理由
模範解答を見る
ミドルウェアは、
一次資料
どれも
- Content Security Policy Level 3 (W3C、英語)。
nonce を 応答ごとに 128 ビット以上の 暗号に 使える 乱数で 作る こと、 meta では Report-Only と report-uri、 frame-ancestors、 sandbox が 効かない こと、 default-src の 無い CSP は 持ち出しを 抑えられないこと - RFC 6797 HTTP Strict Transport Security (HSTS) (IETF、
英語、 。2012年11月) HTTP で 届いた HSTS の 行は 無視される こと、 最初の つなぎの弱さ - HTTP Headers Cheat Sheet (OWASP、英語)。
frame-ancestors が X-Frame-Options を 置き換える こと、 X-Content-Type-Options の nosniff - Penalty Notice, British Airways (ICO、
英語、 。2020年10月16日) 2018年6月22日から 9月5日の 出来事、 スクリプトの ファイルの 書き換えと BAways.com への 送信、 見つける 手立ての 例として ファイルの 完全性の 見張りを 挙げたこと
次へ
次の
