首页 > 解决方案 > jquery.min.js 违反了内联样式的 CSP

问题描述

我想将 CSP 标头添加到网络服务器。我不想添加“不安全内联”。我已经使用“nonce”将所需的内联脚本和样式列入白名单,这似乎工作正常。但是,本地 jquery.min.js 似乎存在一些问题,因为它显示了许多内联样式的 CSP 违规错误。在 Chrome 调试器窗口中检查错误后,它指向 jquery.min.js 的以下行:

a.innerHTML = u[1] + S.htmlPrefilter(o) + u[2],

我不确定这有什么关系。有没有办法在不添加“不安全内联”的情况下消除 jquery.min.js 的这些 CSP 违规错误?

细节:

jquery.min.js 版本 =>v3.5.1

CSP 政策 =>default-src 'self' 'nonce-XXXX'; frame-ancestors 'self'; form-action 'self';

标签: jqueryhttp-headerscontent-security-policy

解决方案


Jquery 与它无关。当您调用//方法将 HTML 代码插入 DOM时使用该a.innerHTML = u[1] + S.htmlPrefilter(o) + u[2]构造。.html().append().prepend()

由于这会导致 CSP 违规,这意味着您插入包含内联样式的 HTML 代码:<tag style='...'<style>...</style>. 您有 2 个选择:

  • 重构 JS 代码以摆脱这种内联样式插入。
  • 使用此 hack替换style=<style>...</style>使用与 CSP 兼容的等效项。
    黑客的想法是覆盖htmlPrefilter()方法,默认情况下它是的,旨在根据您的需要重新定义。

如果style=导致 CSP 违规,您可以使用以下内容:

$.htmlPrefilter = function( html ) {
  // Really it have to be more complicated for replacing a tag's attributes only,
  // not just plain text replacement:
  return ( html + '' ).replace( / style=/gi, ' data-style=' );
  };

那么当使用.html()//方法时,所有.append()的属性都会被替换为一个。.prepend()style=inline_styles_heredata-style='inline_styles_here'

为了 CSP 安全,将真正的 CSS 样式应用于标签,您可以使用如下脚本:

$(function() {   // On page loads
  var tags = document.querySelectorAll('[data-style]');
  for (var tag of tags) {
    var attr = tag.getAttribute('data-style')
    var arr = attr.split(';').map( (el, index) => el.trim() );
    for (var i=0, tmp; i < arr.length; ++i) {
      if (! /:/.test(arr[i]) ) continue;        // Empty or wrong style
      tmp = arr[i].split(':').map( (el, index) => el.trim() );
      tag.style[ camelize(tmp[0]) ] = tmp[1];
      }
    }

  function camelize(str) {
    return str
      .split('-')
      .map( (word, index) => index == 0 ? word : word[0].toUpperCase() + word.slice(1) )
      .join('');
    }

)}

Javascript 不是我的强项,重写上面的脚本以使用原生 jquery 调用。

如果<style>...</style>导致 CSP 违规,您可以重新定义htmlPrefilter()以替换<style><style nonce='value'>,但您必须以某种方式将“nonce”传递给脚本。


推荐阅读