我正在努力保持我的CSP政策尽可能严格。我需要在我的包中包含3d party组件。但它使用element.setAttribute('style'...)
方法来打破CSP。有没有办法允许这个特定的脚本以这种方式内联样式?
答案 0 :(得分:2)
2018-10-06更新
这里的原始答案仍然正确目前 - 因为至少目前在浏览器中实现了CSP ,所以没有办法动态注入样式指定unsafe-inline
,并指定unsafe-inline
基本上否定了CSP的整个目的。
但是,CSP3添加了一个新的unsafe-hashes
表达式,使您可以允许特定的内联脚本/样式。见https://w3c.github.io/webappsec-csp/#unsafe-hashes-usage。有关详细信息,请参阅 Explainer: ‘unsafe-hashes’, ‘unsafe-inline-attributes’ and CSP directive versioning 。但是,它还没有在任何浏览器中发布。因此,目前,以下答案仍然完全适用。
允许style
属性的唯一方法是使用unsafe-inline
。 style
属性来自不同的来源或来自self
并不重要 - 除非您拥有unsafe-inline
,否则它们仍将被视为CSP违规。
具体来说,不会对style
属性起作用的一个解决方案是使用随机数或散列 - 因为在CSP中,仅为{{1}定义了nonce和hash使用}和style
元素;规范有一个Hash usage for style elements部分明确省略了为样式属性定义哈希使用。
因此,即使您在策略中为script
属性的内容指定了正确的哈希值,您的浏览器仍会将其作为违规处理。
最重要的是,因为style
是允许unsafe-inline
属性的唯一方法 - 但使用style
几乎完全违背了让任何CSP政策开始的目的 - 从CSP角度来看,唯一安全的解决方案就是永远不要使用unsafe-inline
属性 - 既不直接来自您自己的标记/代码,也不能使用任何第三方代码。
答案 1 :(得分:1)
是的,有办法。
此处对此有很多讨论:https://github.com/w3c/webappsec-csp/issues/212
最后简要总结了以下内容:
在分析时检查CSP,并阻止分析样式属性。任何直接的操作都会通过。
使用setAttribute
会调用HTML解析器并触发CSP。
所以,而不是:
.setAttribute("style","background:red"); // needs HTML parsing
您需要:
.style.background = "red"; // direct manipulation
一种方法可行而另一种方法不可行听起来很奇怪,我认为这里的理解是HTML属性和DOM属性之间存在细微的差异。 https://joji.me/en-us/blog/html-attribute-vs-dom-property/
答案 2 :(得分:1)
对于正在寻找 jQuery 补丁以将样式属性设置更改为设置正确 css 值的任何人,这里是我使用的一个(源自 this Github,但有一个重要的错误修复以使其正常工作):< /p>
var native = jQuery.attr;
jQuery.attr = function (element, attr, value) {
if (attr === 'style') {
resetStyles(element);
return applyStyles(element, value);
} else {
//native.apply(jQuery, arguments);
return native(element, attr, value);
}
};
function applyStyles(element, styleString) {
if (styleString) {
var styles = styleString.split(';');
styles.forEach(function (styleBit) {
var parts = styleBit.split(':');
var property, value;
if (parts.length === 2) {
property = parts[0].trim();
value = parts[1].trim();
element.style[property] = value;
}
});
return styleString;
}
}
function resetStyles(element) {
var styleList = [].slice.call(element);
styleList.forEach(function (propertyName) {
element.style.removeProperty(propertyName);
});
}
答案 3 :(得分:0)
奇怪为什么新的问题出现了'3岁'的问题,为什么topicstarter的问题仍然没有解决。
使用 element.setAttribute('style', ...)
而不会导致 CSP 违规的问题可以通过 little hack 轻松解决,该 cakeboeing727 started 将有问题的 element.setAttribute('style')
全局替换为安全的 element.style.ptop = '...'
。之后,您可以使用 setAttribute('style')
而不会破坏 CSP,这也将修复 jQuery 和其他库。
仅使用 CSP 本身的解决方案将无效,因为:
'unsafe-hashes'
令牌。