最終更新: 2014-11-06T01:16+0900
GitHubのページ(fizzbuzz.js*)を読んでから、名前付き function expressionの名前 f が外に漏れる IEでは動かないのではないかと思ったのでブコメ(現在は 9 users)を参考にしようと自作のブックマークレットを実行したが反応しない。初めてのことだ。エラーコンソールを開くとこれが出ていた。
時刻: 2014/10/30 21:13:01 警告: CSP WARN: Directive inline script base restriction violated ソースファイル: https://gist.github.com/kazuho/3300555 行: 0 ソースコード: javascript:void function go_hatebukome(url,encode){var prefix="http://b.hatena.ne.jp/entry/",m=url.match(/^http:\/\/([^?#]+)(\?[^#]*)?(#.*)?/);if(m){location.href=prefix+m[1]+encode(m[2]||"");}}(location.href,encodeURIComponent);
CSPというのは Content Security Policyの略のようだ。
Content Security Policy 1.0 (日本語訳) (CSP1.0の仕様。今では CSP1.1もあるみたい)
以下が GitHubから返ってきていた CSPヘッダ(※整形した)。
content-security-policy: default-src *; script-src 'self' https://gist-assets.github.com *.google-analytics.com https://collector-cdn.github.com; frame-src 'self' render.githubusercontent.com https://gist-assets.github.com *.google-analytics.com https://collector-cdn.github.com; style-src 'self' 'unsafe-inline' https://gist-assets.github.com; object-src https://gist-assets.github.com; report-uri /_/csp_reports
まーた Firefoxは自分が User-Agentであることを忘れて仕様に盲従してるのかと思ったのだが(過去に書いた:20121022。外部リンク:「autocomplete=offと人の主体性 - Weblog - Hail2u.net」。仕様を変えるか従うかの選択肢しかないだろうことは理解する)、CSPの script-srcの解説では
'unsafe-inline' が 許容 script ソース集合 の中に含まれていない場合、 UA は:
- インラインスクリプトを実行してはならない( script 要素によるものも, インラインのイベントハンドラによるものも,いずれも)。
- javascript URI に含まれるスクリプトを,実行してはならない。 ( UA は、この制約の施行の下でも, “ブックマークレット” に含まれてるスクリプトについては、実行するべきである。)
というように、ブックマークレットは実行すべきだと明示されている。この直後に書かれている、unsafe-evalが含まれていない場合の制限に引っ掛かるブックマークレットでもない。
'unsafe-eval' が 許容 script ソース集合 の中に含まれていない場合、 UA は:
- eval 演算子, eval 関数のいずれについても、それらの引数を評価せずに,セキュリティ例外を投出しなければならない。 [ECMA-262]
- Function 関数が構築子として呼び出された際は、セキュリティ例外を投出しなければならない。 [ECMA-262]
- setTimeout / setInterval 関数が, callable でない(例えば関数でない)第一引数を伴って呼び出された際には、タイマーを作成せずに,ゼロを返さなければならない。
仕様がどうあれ、ブックマークレットの実行を制限されるいわれはない。ボールはすでにクライアント側に渡っているのだから。
去年の話題「security - How to disable CSP in Firefox for just bookmarklets? - Super User」
そこからリンクされてる3年前の話題「javascript - Does Content Security Policy block bookmarklets? - Stack Overflow」
答えて曰く、グリースモンキーを使え(やなこった)。外部スタイルシートにスクリプトを記述してブックマークレットからロード&実行しろ(面倒だしバッドノウハウ過ぎるし……え?実行も evalもできるの?)。誰にもユーザーがスクリプトを実行するのを阻止することはできない(全く同感!)。CSPを切ることができる、ただし完全に(歴とした証明書を用意できない銀行様みたいな指示を出さないで)。バグとして認識されてはいるみたいよ、こことか、そこを見る限り(23でアップデートを止めたから修正されても関係ないなあ)。
GitHub以外にも広がってきたら CSPを切る。
リンクを追加。
- CSP (Content Security Policy) - Security | MDN (Firefoxでの CSP)
- Content Security Policy 1.0 を Firefox に導入 | Mozilla Developer Street (modest) (仕様が固まった CSP1.0は Firefox23から導入された)
- Content Security Policy · GitHub (GitHubでの CSP。Bookmarkletの問題にも触れてる)
* 現バージョンに固定した URL: https://gist.github.com/kazuho/3300555/3ce4edf79f683b23a7b94678f8c358e997a7f467