Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content security policies not currently supported #166

Closed
thomasnaude opened this issue Dec 24, 2021 · 4 comments · Fixed by #167
Closed

Content security policies not currently supported #166

thomasnaude opened this issue Dec 24, 2021 · 4 comments · Fixed by #167
Labels
enhancement New feature or request

Comments

@thomasnaude
Copy link

thomasnaude commented Dec 24, 2021

Problem
The use of a content security policy is not currently supported when using the page_scriptsoption.
The CSP will prevent the new script from being inserted

// Replace current "sleeping" script with the new "revived" one
curr_script.parentNode.replaceChild(fresh_script, curr_script);

Solution
Add a nonce attribute (if it exists) to the fresh script before adding it to the dom.
Google Tag Manager provides an example of how they do it : https://developers.google.com/tag-platform/tag-manager/web/csp

This would be implemented by adding the code below before loading the scripts :

var nc = document.querySelector('[nonce]');
nc && fresh_script.setAttribute('nonce', nc.nonce || nc.getAttribute('nonce'));

I am happy to provide a PR if you wish

@orestbida
Copy link
Owner

Hi @thomasnaude ,

mhm, this is weird since the script already copies all existing attributes over to the new script:

// Copy attributes over to the new "revived" script
(function(destination, source){
var attr, attributes = source.attributes;
var len = attributes.length;
for(var i=0; i<len; i++){
attr = attributes[i];
destination.setAttribute(attr.nodeName, attr.nodeValue);
}
})(fresh_script, curr_script);

@thomasnaude
Copy link
Author

Hi @orestbida

Thanks for the quick reply.

In Chrome, reading a nonce attribute will return a blank. We need to call .nonce to retrieve its value.
An example:

source.getAttribute('nonce')
=> ''
source.nonce
=> 'aCmw63+gmRXxZGoC03kHXg=='

I guess this must be browser dependent as the suggested GTM implementation is calling both methods (see original post).

@orestbida
Copy link
Owner

Oh, I see!

In this case — instead of adding specific code just for the nonce attribute — we could apply the same approach to all attributes:

(function(destination, source){ 
     var attributes = source.attributes; 
     var len = attributes.length; 
     for(var i=0; i<len; i++){ 
         var attr_name = attributes[i].nodeName;
         destination.setAttribute(attr_name , source[attr_name] || source.getAttribute(attr_name)); 
     } 
 })(fresh_script, curr_script); 

Can you verify that this fixes the issue?

@orestbida orestbida added the enhancement New feature or request label Dec 24, 2021
@thomasnaude
Copy link
Author

I just tested this and it works like a charm !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants