web-dev-qa-db-ja.com

__webpack_nonce___の値をコンテンツセキュリティポリシーと統合するにはどうすればよいですか?

コンテンツセキュリティポリシー の私の理解から、ナンスはリクエストごとに変更する必要があります。つまり、(私が思うに)Webpack構成のビルド時ではなく、クライアントの実行時に生成する必要があります。私は自分のアプリで webpack_nonce機能 をテストしましたが、うまく機能します。

残念ながら、クライアントで実行時に生成されたその値を、index.htmlファイル(または同等のもの)でメタタグとして設定されている実際のCSPポリシーに取得する方法がわかりません。サーバー自体。

クライアントでCSPメタタグを動的に設定できると思いますが、それはセキュリティ上のリスクのようです。 csp-webpack-plugin を試してみました。これは、ビルド時にファイルのハッシュを計算し、それらをindex.htmlに追加します。このプロセスは私には理にかなっています、それは私たちのユースケースをサポートしていませんでした。

Webpack_nonceを使用すると何かが足りないような気がします。

10
Paul Z

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?>'
3
Christian Yang