max*_*tor 6 javascript frontend content-security-policy
我正在努力使我的 CSP 政策尽可能严格。我需要在我的包中包含 3d 派对组件。但它使用了 element.setAttribute('style'...)破坏 CSP 的方法。有没有办法允许这个特定的脚本以这种方式内联样式?
2018-10-06 更新
\n\n这里的原始答案目前仍然正确\xe2\x80\x94 因为至少在浏览器中当前实现的CSP 中,\xe2\x80\x99s 仍然无法在不指定 和 的情况下动态注入unsafe-inline样式unsafe-inline基本上否定CSP 的全部目的。
但是,CSP3 添加了一个新unsafe-hashes表达式,使您能够允许特定的内联脚本/样式。请参阅https://w3c.github.io/webappsec-csp/#unsafe-hashes-usage,并参阅解释器: \xe2\x80\x98unsafe-hashes\xe2\x80\x99, \xe2\x80\x98unsafe-inline- attribute\xe2\x80\x99 和 CSP 指令版本控制。不过,它还没有在任何浏览器中发布。所以暂时来说,下面的答案仍然完全适用。
允许style属性的唯一方法是使用unsafe-inline. style\xe2\x80\x99属性是否来自不同来源或来自\xe2\x80\x94并不重要,它们self\xe2\x80\x99 仍然会被视为 CSP 违规,除非您有unsafe-inline.
具体来说,一种对属性不起作用的解决方案是使用style随机数或散列xe2\x80\x94,因为在 CSP 中,随机数和散列用法仅针对style和script elements定义;该规范有一个样式元素的哈希用法部分,该部分明确省略了定义样式属性的哈希用法的哈希用法。
因此,即使在您的策略中您为 a 的内容指定了正确的哈希值,style,您的浏览器仍会将其视为违规。
底线是,因为这unsafe-inline是允许style属性 \xe2\x80\x94 的唯一方法,但使用unsafe-inline几乎完全违背了以 \xe2\x80\x94 开头的任何 CSP 策略的目的,从 CSP 角度来看,唯一安全的解决方案就是从不使用style切勿直接从您自己的标记/代码或通过任何第三方代码
是的,有办法。
这里有很多讨论:https : //github.com/w3c/webappsec-csp/issues/212
最后简要总结一下:
CSP 在解析时检查并阻止解析样式属性。任何直接操作都要经过。
使用setAttribute调用 HTML 解析器并触发 CSP。
所以,而不是:
.setAttribute("style","background:red"); // needs HTML parsing
Run Code Online (Sandbox Code Playgroud)
你需要:
.style.background = "red"; // direct manipulation
Run Code Online (Sandbox Code Playgroud)
一种方法有效而另一种方法无效听起来可能很奇怪,我认为这里的理解是 HTML 属性和 DOM 属性之间存在细微差别。https://joji.me/en-us/blog/html-attribute-vs-dom-property/
小智 5
对于任何寻找 jQuery 补丁来将样式属性设置更改为设置正确的 css 值的人,这里是我使用的一个(源自此 Github,但修复了一个重要的错误以使其正常工作):
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);
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1527 次 |
| 最近记录: |