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

feat: meta based csp #228

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions scripts/csp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"default-src": [
"'self'"
],
"script-src": [
"'self'",
"https://rum.hlx.page/"
],
"connect-src": [
"'self'",
"https://rum.hlx.page/"
]
}
18 changes: 18 additions & 0 deletions scripts/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,29 @@ async function loadEager(doc) {
}
}

/**
* sets the Content-Security-Policy meta tag to the document based on JSON file
*/

async function setCSP() {
const resp = await fetch(`${window.hlx.codeBasePath}/scripts/csp.json`);
const json = await resp.json();
const directives = Object.keys(json);
const policy = directives.map((directive) => `${directive} ${json[directive].join(' ')}`).join('; ');
const meta = document.createElement('meta');
meta.setAttribute('http-equiv', 'Content-Security-Policy');
meta.setAttribute('content', policy);
document.addEventListener('securitypolicyviolation', (e) => sampleRUM('csperror', { source: `${e.documentURI}:${e.lineNumber}:${e.columnNumber}`, target: e.blockedURI }));
document.head.appendChild(meta);
davidnuescheler marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Loads everything that doesn't need to be delayed.
* @param {Element} doc The container element
*/
async function loadLazy(doc) {
await setCSP();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd check if this is effective in blocking eagerly loaded resources that violate the CSP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not sure that i am really that worried about the CSPs protecting block code...
to me this probably has to be in place before we execute untrusted code, eg. martech stack, so one could argue that this is in the wrong place altogether. so to a certain extent i think i am saying i don't even know when this should be loaded, so i am not really sure that an await really makes a difference here...

i am somewhat doubtful of the allowlist based approach altogether, so maybe a nonce based strict-dynamic approach would be the right thing here, but i definitely don't know enough about the repercussions of that vis-a-vis the somewhat questionable benefit of CSPs around XSS attacks on franklin sites.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... 99.34% of hosts with CSP use policies that offer no benefit against XSS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revisiting this, I think this is right, but only the first step. The next step should be @chicharr's lightweight tag management controlling the CSP


const main = doc.querySelector('main');
await loadBlocks(main);

Expand Down