jquery - 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';
解决方案
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_here
data-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”传递给脚本。
推荐阅读
- laravel - Laravel Slug 更新记录
- javascript - 1234.1234,123.12,0100.111,XXXX.XXXX 的 Java 脚本正则表达式
- sql - Redshift - 在 where 子句中将 UTC 时间转换为本地时间时出错
- vba - 从 xmlhttp.responseText 获取数据到 excel
- node.js - 如何使用 bitcore-lib (NodeJs) 获得交易的最低费用?
- jcreator - 初学者在格式字符串上的挣扎
- c++ - 如何使用谷歌测试用例测试迭代器值?
- sql-server - SSMS 中数据库名称后的 (Synchronized) 是什么意思。
- android - PC usb主机通过libusb与Android配件模式通信
- javascript - 在 create-react-app 中修改 antd 主题而不弹出 webpack