Как интегрировать значение __webpack_nonce___ в мою политику безопасности контента?

Насколько я понимаю политику безопасности контента, одноразовый номер должен измениться на каждый запрос. Это означает (я думаю), что он должен генерироваться во время выполнения на клиенте, а не во время сборки в конфигурации Webpack. Я протестировал функциональность webpack_nonce в своем приложении, и она отлично работает.

К сожалению, я не уверен, как получить это значение, сгенерированное во время выполнения на клиенте, для фактической политики CSP, которая либо задана как метатег в файле index.html (или каком-то эквиваленте), либо на сам сервер.

Я полагаю, вы могли бы динамически установить метатег CSP на клиенте, но это похоже на угрозу безопасности. Я экспериментировал с csp-webpack-plugin, который вычисляет хэши файлов. во время сборки, а затем добавляет их в index.html. Этот процесс имеет смысл для меня, он просто не поддерживает наш вариант использования.

Мне просто кажется, что я что-то упустил при использовании webpack_nonce.


person Paul Z    schedule 03.04.2018    source источник


Ответы (1)


Мы смогли получить динамический одноразовый номер, заставив веб-пакет построить нашу индексную страницу (например, через HtmlWebpackPlugin) в качестве шаблона, а затем обслуживать ее динамически. Таким образом, вы можете установить __webpack_nonce__ в выражение интерполяции, такое как <%=nonce%>, и механизм представления сервера сможет подставить ваш динамический одноразовый номер во время загрузки страницы. Например, если вы используете экспресс:

Конфигурация вебпака:

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%>';

Экспресс приложение:

// 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 будет интерполировать выражение одноразового номера во время сборки, а не во время выполнения.

Экспресс приложение:

const ejs = require('ejs);
ejs.delimiter = '?'; // Means instead use __webpack_nonce__ = '<?=nonce?>'
person Christian Yang    schedule 18.04.2018
comment
Эй, христианин, а как насчет стилей? для csp также требуются теги стиля. Не могли бы вы сделать что-то подобное здесь с чем-то вроде плагина miniss? - person Huy Tran; 14.03.2021
comment
Я не пробовал напрямую, но похоже, что плагин style-loader поддерживает __webpack_nonce__, поэтому аналогичный подход должен работать: webpack.js.org/loaders/style-loader/#__webpack_nonce__ - person Christian Yang; 18.03.2021
comment
Уважаемый Кристиан, не могли бы вы опубликовать минимальный пример на GitHub, пожалуйста? - person Nikolay Schamberg; 24.06.2021