Wednesday, June 5, 2024
177
rated 0 times [  182] [ 5]  / answers: 1 / hits: 30112  / 7 Years ago, wed, february 22, 2017, 12:00:00

I turned on Content Security Policy on my server with this command in my Apache2-configuration:



Header set Content-Security-Policy-Report-Only default-src 'self'


(I set it to ...-Report-Only to only report errors, without really blocking something while developing.)



This setting produces an error that I don't understand. But I can reproduce it:



This is the simplified html-code:



<!DOCTYPE HTML>
<html lang=en>
<head>
<script src=/js/test.js></script>
<title>test</title>
</head>
<body></body>
</html>


As you see, no inline-script and no inline-style (no style at all) and a completely empty body.



And here is the Javascript-file 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;
};


This script adds two div's to the body, and inserts a paragraph with a text into one of the divs. Then it changes the color of the text to red. At the end it makes a copy of the content of this div and insert this copy into the other div.



I think I've done all right, but when I open this document in my browser, I get this error reported in the console of 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




(the reported line number 0 is obviously not correct)

This is what Opera and Chrome write to the console:




[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




(line 15 is the manipulation of innerHTML)



This error appears only, when I set any style to a part of the document (p1.style.color = red;) and then make a copy of a part that contains the styled part (copy.innerHTML = original.innerHTML).



My questions:




  • Why does this error appear? (I want to understand why it reports inline style although there is no inline styling)

  • How can I avoid this error?



I have no realistic chance to change the part where the original is manipulated. All I can change is this line:



document.getElementById('copy').innerHTML = document.getElementById('original').innerHTML;





Addendum



Sorry, I wasn't clear enough about this:



I do NOT want to change the CSP-Header. There is a good reason, why inline-style has to be forbidden. See XSS attacks and style attributes and similar Questions.



I want:




  1. Understand why my JavaScript code produces an inline-style-error.

  2. A script that doesn't produce such an error.


More From » content-security-policy

 Answers
8

Updated:


Because you are converting from a DOMElement to text(via innerHTML) any elements with modified styles get converted into inline styles. I've included an example to illustrate this.




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>




Therefore when you set the innerHTML of the copy, you are including the styles that had modified the element as inline styles which violates your policy.


You could technically make a duplicate copy of the DOM element instead, and insert it to the DOM tree directly. For that, take a look at the MDN Documentation for Cloning Nodes. My old answer is still valid in the case the DOM manipulation is not viable.


Old Answer:


According to the MDN documentation on CSP you can solve it by sending the following header:


style-src 'unsafe-inline' 'self'; default-src 'self';

Here is the documentation for default-src.


[#58813] Tuesday, February 21, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
cierra

Total Points: 504
Total Questions: 108
Total Answers: 109

Location: Northern Mariana Islands
Member since Fri, Jan 15, 2021
3 Years ago
;