web-dev-qa-db-ja.com

CSPヘッダーが設定されている場合の "new Function()"に関するunderscore.jsの問題

Underscore.jsでは、テンプレートのレンダリングが 'unsafe-eval'プロパティの違反を引き起こし、次の行でCSPエラーが発生します。

render = new Function(settings.variable || 'obj', '_', source);

一部のフォーラムでのこれに対する解決策は、 Chromeのドキュメント に従ってアンダースコアをサンドボックス化することです。

しかし、このソリューションは、ブラウザーが異なるユーザー数が多いWebベースのアプリケーションではどのように機能しますか?この問題の代替ソリューションはありますか?私が取り組んでいるアプリケーションは大きくて重いので、コードの変更にはかなりの時間がかかることに注意してください。

9
hshantanu

html5rocks から、Content-Security-Policyヘッダーにノンスを設定します。

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

Nonceをページのどこかに配置します。

...
<body data-nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
...

スクリプトでアンダースコアの使用を開始する前に、問題のノンス値を使用して以下の関数を呼び出します。

function handleFnNonceRequirement(nonce) {
    window.Function = function () {
        var renderNode = document.createElement("script"),
            len = arguments.length,
            source = arguments[len-1],
            args = [];

        if ( 1 < len ) {
            for ( var i=0; i<(len-1); i++ ) {
                args.Push(arguments[i]);
            }
        }

        renderNode.text = "function __ifYouAbsolutelyMustUseIt() { return function("+args.join(", ")+") {" + source + "}}";
        renderNode.setAttribute('nonce', nonce);

        document.head.appendChild(renderNode).parentNode.removeChild(renderNode);
        return __ifYouAbsolutelyMustUseIt();
    };
}

handleFnNonceRequirement(document.getElementsByTagName("BODY")[0].getAttribute('data-nonce'));

これよりも良い方法があるといいのですが。

3
Sand

@ Sand によって提案された解決策は私にとってうまくいきました。ただし、コードを複数のページに簡単に配置できるように、全体をより自己完結させるために、script要素自体からナンスを取得します。

<script type="text/javascript" id="noncense" nonce="...">
   function handleFnNonceRequirement(nonce) {
    .
    .
    .
   }
   handleFnNonceRequirement($("#noncense")[0].nonce);
</script>

このアプローチに問題がある場合はお知らせください。

0
Sushil