"inline-style"-内容安全策略错误,Javascript
"inline-style"-Error with Content Security Policy and Javascript
我在我的 Apache2 配置中使用以下命令在我的服务器上启用了内容安全策略:
Header set Content-Security-Policy-Report-Only "default-src 'self'"
(我将其设置为 ...-Report-Only
以仅报告错误,而不会在开发时真正阻止某些内容。)
此设置产生了一个我不明白的错误。但我可以复制它:
这是简化的 html-代码:
<!DOCTYPE HTML>
<html lang="en">
<head>
<script src="/js/test.js"></script>
<title>test</title>
</head>
<body></body>
</html>
如您所见,没有内联脚本,也没有内联样式(根本没有样式),主体完全是空的。
这是 Javascript 文件 test.js:
window.onload = function () {
//create a paragraph with a red text to have some content
//in my "real" problem, this part is very much code (more than 1000 lines)
document.body.innerHTML = '<div id="original"></div><div id="copy"></div>';
var p1 = document.createElement('p');
var t1 = document.createTextNode('some text');
p1.appendChild(t1);
document.getElementById('original').appendChild(p1);
//set some style within this content
p1.style.color = "red";
//-----------------------------------
//make a copy of this content
document.getElementById('copy').innerHTML = document.getElementById('original').innerHTML;
};
此脚本将两个 div 添加到正文,并将带有文本的段落插入其中一个 div。然后它将文本的颜色更改为红色。最后它复制了这个 div 的内容并将这个副本插入到另一个 div.
我觉得我做的很好,但是当我在浏览器中打开这个文档时,我在 Safari 的控制台中报告了这个错误:
[Report Only] Refused to apply a stylesheet because its hash, its nonce, or 'unsafe-inline' appears in neither the style-src directive nor the default-src directive of the Content Security Policy.
test.js:0
(报告的行号“0”显然不正确)
这是 Opera 和 Chrome 写入控制台的内容:
[Report Only] Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-ZBTj5RHLnrF+IxdRZM2RuLfjTJQXNSi7fLQHr09onfY='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
window.onload @ test.js:15
(第15行是对innerHTML的操作)
仅当我为文档的一部分设置任何样式 (p1.style.color = "red";
),然后复制包含样式部分 (copy.innerHTML = original.innerHTML
) 的部分时,才会出现此错误。
我的问题:
- 为什么会出现这个错误? (我想明白为什么它报告 "inline style" 虽然没有内联样式)
- 如何避免这个错误?
我没有现实的机会去改变原作被操纵的部分。我只能更改这一行:
document.getElementById('copy').innerHTML = document.getElementById('original').innerHTML;
附录
抱歉,我对此不够清楚:
我不想更改 CSP-Header。有一个很好的理由,为什么必须禁止内联样式。请参阅 XSS attacks and style attributes 和类似问题。
我要:
- 了解为什么我的 JavaScript 代码会产生内联样式错误。
- 不会产生此类错误的脚本。
已更新:
因为您要将 DOM 元素转换为文本(通过 innerHTML),所以任何具有修改样式的元素都会转换为内联样式。我提供了一个示例来说明这一点。
var el = document.getElementById('sample'),
output = document.getElementById('output'),
affect = document.getElementById('affected');
affect.style.backgroundColor = "#369";
affect.style.color = "#FFF";
output.innerText+=el.innerHTML;
#sample {
margin:10px;
}
#output {
margin: 10px;
}
<div id="sample">
<div id="affected">
Sample DIV
</div>
</div>
<div id="output">
Output:
</div>
因此,当您设置副本的 innerHTML 时,您将修改元素的样式包含为内联样式,这违反了您的政策。
从技术上讲,您可以复制 DOM 元素,然后将其直接插入到 DOM 树中。为此,请查看克隆节点的 MDN Documentation。在 DOM 操作不可行的情况下,我的旧答案仍然有效。
旧答案:
根据 CSP 上的 MDN documentation,您可以通过发送以下 header:
来解决它
style-src 'unsafe-inline' 'self'; default-src 'self';
这是 default-src 的 documentation。
我在我的 Apache2 配置中使用以下命令在我的服务器上启用了内容安全策略:
Header set Content-Security-Policy-Report-Only "default-src 'self'"
(我将其设置为 ...-Report-Only
以仅报告错误,而不会在开发时真正阻止某些内容。)
此设置产生了一个我不明白的错误。但我可以复制它:
这是简化的 html-代码:
<!DOCTYPE HTML>
<html lang="en">
<head>
<script src="/js/test.js"></script>
<title>test</title>
</head>
<body></body>
</html>
如您所见,没有内联脚本,也没有内联样式(根本没有样式),主体完全是空的。
这是 Javascript 文件 test.js:
window.onload = function () {
//create a paragraph with a red text to have some content
//in my "real" problem, this part is very much code (more than 1000 lines)
document.body.innerHTML = '<div id="original"></div><div id="copy"></div>';
var p1 = document.createElement('p');
var t1 = document.createTextNode('some text');
p1.appendChild(t1);
document.getElementById('original').appendChild(p1);
//set some style within this content
p1.style.color = "red";
//-----------------------------------
//make a copy of this content
document.getElementById('copy').innerHTML = document.getElementById('original').innerHTML;
};
此脚本将两个 div 添加到正文,并将带有文本的段落插入其中一个 div。然后它将文本的颜色更改为红色。最后它复制了这个 div 的内容并将这个副本插入到另一个 div.
我觉得我做的很好,但是当我在浏览器中打开这个文档时,我在 Safari 的控制台中报告了这个错误:
[Report Only] Refused to apply a stylesheet because its hash, its nonce, or 'unsafe-inline' appears in neither the style-src directive nor the default-src directive of the Content Security Policy.
test.js:0
(报告的行号“0”显然不正确)
这是 Opera 和 Chrome 写入控制台的内容:
[Report Only] Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-ZBTj5RHLnrF+IxdRZM2RuLfjTJQXNSi7fLQHr09onfY='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
window.onload @ test.js:15
(第15行是对innerHTML的操作)
仅当我为文档的一部分设置任何样式 (p1.style.color = "red";
),然后复制包含样式部分 (copy.innerHTML = original.innerHTML
) 的部分时,才会出现此错误。
我的问题:
- 为什么会出现这个错误? (我想明白为什么它报告 "inline style" 虽然没有内联样式)
- 如何避免这个错误?
我没有现实的机会去改变原作被操纵的部分。我只能更改这一行:
document.getElementById('copy').innerHTML = document.getElementById('original').innerHTML;
附录
抱歉,我对此不够清楚:
我不想更改 CSP-Header。有一个很好的理由,为什么必须禁止内联样式。请参阅 XSS attacks and style attributes 和类似问题。
我要:
- 了解为什么我的 JavaScript 代码会产生内联样式错误。
- 不会产生此类错误的脚本。
已更新:
因为您要将 DOM 元素转换为文本(通过 innerHTML),所以任何具有修改样式的元素都会转换为内联样式。我提供了一个示例来说明这一点。
var el = document.getElementById('sample'),
output = document.getElementById('output'),
affect = document.getElementById('affected');
affect.style.backgroundColor = "#369";
affect.style.color = "#FFF";
output.innerText+=el.innerHTML;
#sample {
margin:10px;
}
#output {
margin: 10px;
}
<div id="sample">
<div id="affected">
Sample DIV
</div>
</div>
<div id="output">
Output:
</div>
因此,当您设置副本的 innerHTML 时,您将修改元素的样式包含为内联样式,这违反了您的政策。
从技术上讲,您可以复制 DOM 元素,然后将其直接插入到 DOM 树中。为此,请查看克隆节点的 MDN Documentation。在 DOM 操作不可行的情况下,我的旧答案仍然有效。
旧答案:
根据 CSP 上的 MDN documentation,您可以通过发送以下 header:
来解决它style-src 'unsafe-inline' 'self'; default-src 'self';
这是 default-src 的 documentation。