jquery.min.js 违反了 inline-style 的 CSP
jquery.min.js violates CSP for inline-style
我想将 CSP header 添加到网络服务器。我不想添加 'unsafe-inline'。我已经使用 'nonce' 将所需的内联脚本和样式列入白名单,这似乎工作正常。但是,local jquery.min.js 似乎存在一些问题,因为它显示了许多内联样式的 CSP 违规错误。检查 Chrome 调试器 window 中的错误后,它指向 jquery.min.js 的以下行:
a.innerHTML = u[1] + S.htmlPrefilter(o) + u[2],
我不确定这有什么关系。有没有办法在不添加 'unsafe-inline' 的情况下消除 jquery.min.js 的这些 CSP 违规错误?
详情:
jquery.min.js 版本 => v3.5.1
CSP 政策 => default-src 'self' 'nonce-XXXX'; frame-ancestors 'self'; form-action 'self';
Jquery与此无关。当您调用 .html()
/ .append()
/ .prepend()
方法将 HTML 代码插入 DOM.[=33= 时,将使用 a.innerHTML = u[1] + S.htmlPrefilter(o) + u[2]
构造]
由于这会导致 CSP 违规,这意味着您插入 HTML 包含内联样式的代码:<tag style='...'
或 <style>...</style>
。您有 2 个选择:
- 重构 JS 代码以摆脱这种内联样式插入。
- 使用 this hack 将
style=
或 <style>...</style>
替换为与 CSP 兼容的等效项。
黑客的想法是覆盖 htmlPrefilter()
方法,默认情况下它是 empty 并打算根据您的需要重新定义。
如果 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' 到脚本。
我想将 CSP header 添加到网络服务器。我不想添加 'unsafe-inline'。我已经使用 'nonce' 将所需的内联脚本和样式列入白名单,这似乎工作正常。但是,local jquery.min.js 似乎存在一些问题,因为它显示了许多内联样式的 CSP 违规错误。检查 Chrome 调试器 window 中的错误后,它指向 jquery.min.js 的以下行:
a.innerHTML = u[1] + S.htmlPrefilter(o) + u[2],
我不确定这有什么关系。有没有办法在不添加 'unsafe-inline' 的情况下消除 jquery.min.js 的这些 CSP 违规错误?
详情:
jquery.min.js 版本 => v3.5.1
CSP 政策 => default-src 'self' 'nonce-XXXX'; frame-ancestors 'self'; form-action 'self';
Jquery与此无关。当您调用 .html()
/ .append()
/ .prepend()
方法将 HTML 代码插入 DOM.[=33= 时,将使用 a.innerHTML = u[1] + S.htmlPrefilter(o) + u[2]
构造]
由于这会导致 CSP 违规,这意味着您插入 HTML 包含内联样式的代码:<tag style='...'
或 <style>...</style>
。您有 2 个选择:
- 重构 JS 代码以摆脱这种内联样式插入。
- 使用 this hack 将
style=
或<style>...</style>
替换为与 CSP 兼容的等效项。
黑客的想法是覆盖htmlPrefilter()
方法,默认情况下它是 empty 并打算根据您的需要重新定义。
如果 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' 到脚本。