コンテンツセキュリティポリシー の私の理解から、ナンスはリクエストごとに変更する必要があります。つまり、(私が思うに)Webpack構成のビルド時ではなく、クライアントの実行時に生成する必要があります。私は自分のアプリで webpack_nonce機能 をテストしましたが、うまく機能します。
残念ながら、クライアントで実行時に生成されたその値を、index.htmlファイル(または同等のもの)でメタタグとして設定されている実際のCSPポリシーに取得する方法がわかりません。サーバー自体。
クライアントでCSPメタタグを動的に設定できると思いますが、それはセキュリティ上のリスクのようです。 csp-webpack-plugin を試してみました。これは、ビルド時にファイルのハッシュを計算し、それらをindex.htmlに追加します。このプロセスは私には理にかなっています、それは私たちのユースケースをサポートしていませんでした。
Webpack_nonceを使用すると何かが足りないような気がします。
Webpackにインデックスページをテンプレートとして構築させ(HtmlWebpackPlugin経由など)、動的に提供することで、動的なナンスを取得することができました。このようにして、__webpack_nonce__
を<%=nonce%>
のような補間式に設定でき、サーバービューエンジンはページの読み込み時に動的ナンスにサブインできます。たとえば、Expressを使用している場合:
Webpack構成:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
filename: __dirname + '/dist/index.ejs',
})
]
}
Webpackエントリポイント(index.js):
__webpack_nonce__ = '<%=nonce%>';
Expressアプリ:
// Generate dynamic nonce on each request cycle
const uuid = require('node-uuid');
app.use((req, res, next) => {
res.locals.nonce = uuid.v4();
next();
});
app.set('view engine', 'ejs');
app.route('/').get((req, res, next) => {
res.render('path/to/index.ejs', { nonce: res.locals.nonce });
});
挿入された<script>
タグには、リテラル属性nonce=<%=nonce%>
が追加され、サーバーはページを提供するときにこれを補間します。
HtmlWebpackPluginでカスタムテンプレートを使用する場合は、ejs
に別の補間区切り文字を設定することをお勧めします。そうしないと、Webpackは実行時ではなくビルド時にnonce式を補間します。
Expressアプリ:
const ejs = require('ejs);
ejs.delimiter = '?'; // Means instead use __webpack_nonce__ = '<?=nonce?>'