diff --git a/package-lock.json b/package-lock.json
index 289e6c20..a7bc0f05 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,6 @@
"mdast-util-to-string": "4.0.0",
"micromark-util-subtokenize": "2.0.4",
"mime": "4.0.6",
- "parse5-html-rewriting-stream": "7.0.0",
"rehype-format": "5.0.1",
"rehype-parse": "9.0.1",
"remark-parse": "11.0.0",
@@ -10783,20 +10782,6 @@
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
- "node_modules/parse5-html-rewriting-stream": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz",
- "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==",
- "license": "MIT",
- "dependencies": {
- "entities": "^4.3.0",
- "parse5": "^7.0.0",
- "parse5-sax-parser": "^7.0.0"
- },
- "funding": {
- "url": "https://github.com/inikulin/parse5?sponsor=1"
- }
- },
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
@@ -10818,6 +10803,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz",
"integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"parse5": "^7.0.0"
diff --git a/package.json b/package.json
index 4b3a455f..23210d30 100644
--- a/package.json
+++ b/package.json
@@ -57,7 +57,6 @@
"mdast-util-to-string": "4.0.0",
"micromark-util-subtokenize": "2.0.4",
"mime": "4.0.6",
- "parse5-html-rewriting-stream": "7.0.0",
"rehype-format": "5.0.1",
"rehype-parse": "9.0.1",
"remark-parse": "11.0.0",
diff --git a/src/html-pipe.js b/src/html-pipe.js
index e5221e2b..4ddee834 100644
--- a/src/html-pipe.js
+++ b/src/html-pipe.js
@@ -149,7 +149,6 @@ export async function htmlPipe(state, req) {
if (state.content.sourceBus === 'code' || state.info.originalExtension === '.md') {
state.timer?.update('serialize');
- await setCustomResponseHeaders(state, req, res);
await renderCode(state, req, res);
} else {
state.timer?.update('parse');
@@ -166,7 +165,6 @@ export async function htmlPipe(state, req) {
await createPictures(state);
await extractMetaData(state, req);
await addHeadingIds(state);
- await setCustomResponseHeaders(state, req, res);
await render(state, req, res);
state.timer?.update('serialize');
await tohtml(state, req, res);
@@ -174,6 +172,7 @@ export async function htmlPipe(state, req) {
}
setLastModified(state, res);
+ await setCustomResponseHeaders(state, req, res);
await setXSurrogateKeyHeader(state, req, res);
} catch (e) {
res.error = e.message;
diff --git a/src/steps/csp.js b/src/steps/csp.js
deleted file mode 100644
index 4c4b6b5d..00000000
--- a/src/steps/csp.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2024 Adobe. All rights reserved.
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License. You may obtain a copy
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
- * OF ANY KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-import crypto from 'crypto';
-import { select } from 'hast-util-select';
-import { remove } from 'unist-util-remove';
-import { RewritingStream } from 'parse5-html-rewriting-stream';
-import { visit } from 'unist-util-visit';
-
-export const NONCE_AEM = '\'nonce-aem\'';
-
-/**
- * Parse a CSP string into its directives
- * @param {string | undefined | null} csp
- * @returns {Object}
- */
-function parseCSP(csp) {
- if (!csp) {
- return {};
- }
-
- const parts = csp.split(';');
- const result = {};
- parts.forEach((part) => {
- const [directive, ...values] = part.trim().split(' ');
- result[directive] = values.join(' ');
- });
- return result;
-}
-
-/**
- * Computes where nonces should be applied
- * @param {string | null | undefined} metaCSPText The actual CSP value from the meta tag
- * @param {string | null | undefined} headersCSPText The actual CSP value from the headers
- * @returns {scriptNonce: boolean, styleNonce: boolean}
- */
-function shouldApplyNonce(metaCSPText, headersCSPText) {
- const metaBased = parseCSP(metaCSPText);
- const headersBased = parseCSP(headersCSPText);
- return {
- scriptNonce: metaBased['script-src']?.includes(NONCE_AEM)
- || headersBased['script-src']?.includes(NONCE_AEM),
- styleNonce: metaBased['style-src']?.includes(NONCE_AEM)
- || headersBased['style-src']?.includes(NONCE_AEM),
- };
-}
-
-/**
- * Create a nonce for CSP
- * @returns {string}
- */
-function createNonce() {
- return crypto.randomBytes(18).toString('base64');
-}
-
-/**
- * Get the applied CSP header from a response
- * @param {PipelineResponse} res
- * @returns {string}
- */
-export function getHeaderCSP(res) {
- return res.headers?.get('content-security-policy');
-}
-
-/**
- * Apply CSP with nonces on an AST
- * @param {PipelineResponse} res
- * @param {Object} tree
- * @param {Object} metaCSP
- * @param {string} headersCSP
- */
-function createAndApplyNonceOnAST(res, tree, metaCSP, headersCSP) {
- const nonce = createNonce();
- const { scriptNonce, styleNonce } = shouldApplyNonce(metaCSP?.properties.content, headersCSP);
-
- if (metaCSP) {
- metaCSP.properties.content = metaCSP.properties.content.replaceAll(NONCE_AEM, `'nonce-${nonce}'`);
- }
-
- if (headersCSP) {
- res.headers.set('content-security-policy', headersCSP.replaceAll(NONCE_AEM, `'nonce-${nonce}'`));
- }
-
- visit(tree, (node) => {
- if (scriptNonce && node.tagName === 'script' && node.properties?.nonce === 'aem') {
- node.properties.nonce = nonce;
- return;
- }
-
- if (styleNonce
- && (node.tagName === 'style' || (node.tagName === 'link' && node.properties?.rel?.[0] === 'stylesheet'))
- && node.properties?.nonce === 'aem'
- ) {
- node.properties.nonce = nonce;
- }
- });
-}
-
-export function checkResponseBodyForMetaBasedCSP(res) {
- return res.body?.includes('http-equiv="content-security-policy"')
- || res.body?.includes('http-equiv="Content-Security-Policy"');
-}
-
-export function checkResponseBodyForAEMNonce(res) {
- /*
- we only look for 'nonce-aem' (single quote) to see if there is a meta CSP with nonce
- we don't want to generate nonces if they appear just on script/style tags,
- as those have no effect without the actual CSP meta (or header).
- this means it is ok to not check for the "nonce-aem" (double quotes)
- */
- return res.body?.includes(NONCE_AEM);
-}
-
-export function getMetaCSP(tree) {
- return select('meta[http-equiv="content-security-policy"]', tree)
- || select('meta[http-equiv="Content-Security-Policy"]', tree);
-}
-
-export function contentSecurityPolicyOnAST(res, tree) {
- const metaCSP = getMetaCSP(tree);
- const headersCSP = getHeaderCSP(res);
-
- if (!metaCSP && !headersCSP) {
- // No CSP defined
- return;
- }
-
- // CSP with nonce
- if (metaCSP?.properties.content.includes(NONCE_AEM) || headersCSP?.includes(NONCE_AEM)) {
- createAndApplyNonceOnAST(res, tree, metaCSP, headersCSP);
- }
-
- if (metaCSP?.properties['move-as-header'] === 'true') {
- if (!headersCSP) {
- // if we have a CSP in meta but no CSP in headers
- // we can move the CSP from meta to headers, if requested
- res.headers.set('content-security-policy', metaCSP.properties.content);
- remove(tree, null, metaCSP);
- } else {
- delete metaCSP.properties['move-as-header'];
- }
- }
-}
-
-export function contentSecurityPolicyOnCode(state, res) {
- if (state.type !== 'html') {
- return;
- }
-
- const cspHeader = getHeaderCSP(res);
- if (!(
- cspHeader?.includes(NONCE_AEM)
- || (checkResponseBodyForMetaBasedCSP(res) && checkResponseBodyForAEMNonce(res))
- )) {
- return;
- }
-
- const nonce = createNonce();
- let { scriptNonce, styleNonce } = shouldApplyNonce(null, cspHeader);
-
- const rewriter = new RewritingStream();
- const chunks = [];
-
- rewriter.on('startTag', (tag, rawHTML) => {
- if (tag.tagName === 'meta'
- && tag.attrs.find(
- (attr) => attr.name.toLowerCase() === 'http-equiv' && attr.value.toLowerCase() === 'content-security-policy',
- )
- ) {
- const contentAttr = tag.attrs.find((attr) => attr.name.toLowerCase() === 'content');
- if (contentAttr) {
- ({ scriptNonce, styleNonce } = shouldApplyNonce(contentAttr.value, cspHeader));
-
- if (!cspHeader && tag.attrs.find((attr) => attr.name === 'move-as-header' && attr.value === 'true')) {
- res.headers.set('content-security-policy', contentAttr.value.replaceAll(NONCE_AEM, `'nonce-${nonce}'`));
- return; // don't push the chunk so it gets removed from the response body
- }
- chunks.push(rawHTML.replaceAll(NONCE_AEM, `'nonce-${nonce}'`));
- return;
- }
- }
-
- if (scriptNonce && tag.tagName === 'script' && tag.attrs.find((attr) => attr.name === 'nonce' && attr.value === 'aem')) {
- chunks.push(rawHTML.replace(/nonce="aem"/i, `nonce="${nonce}"`));
- return;
- }
-
- if (styleNonce && (tag.tagName === 'style' || tag.tagName === 'link') && tag.attrs.find((attr) => attr.name === 'nonce' && attr.value === 'aem')) {
- chunks.push(rawHTML.replace(/nonce="aem"/i, `nonce="${nonce}"`));
- return;
- }
-
- chunks.push(rawHTML);
- });
-
- rewriter.on('data', (data) => {
- chunks.push(data);
- });
-
- rewriter.write(res.body);
- rewriter.end();
- res.body = chunks.join('');
- if (cspHeader) {
- res.headers.set('content-security-policy', cspHeader.replaceAll(NONCE_AEM, `'nonce-${nonce}'`));
- }
-}
diff --git a/src/steps/fetch-404.js b/src/steps/fetch-404.js
index 1c65bbf5..592406a0 100644
--- a/src/steps/fetch-404.js
+++ b/src/steps/fetch-404.js
@@ -10,7 +10,6 @@
* governing permissions and limitations under the License.
*/
import { extractLastModified, recordLastModified } from '../utils/last-modified.js';
-import { contentSecurityPolicyOnCode } from './csp.js';
import { computeContentPathKey, computeCodePathKey } from './set-x-surrogate-key-header.js';
/**
@@ -35,7 +34,6 @@ export default async function fetch404(state, req, res) {
// keep 404 response status
res.body = ret.body;
- contentSecurityPolicyOnCode(state, res);
res.headers.set('last-modified', ret.headers.get('last-modified'));
res.headers.set('content-type', 'text/html; charset=utf-8');
}
diff --git a/src/steps/render-code.js b/src/steps/render-code.js
index 46a00592..4c954568 100644
--- a/src/steps/render-code.js
+++ b/src/steps/render-code.js
@@ -10,9 +10,6 @@
* governing permissions and limitations under the License.
*/
import mime from 'mime';
-import {
- contentSecurityPolicyOnCode,
-} from './csp.js';
const CHARSET_RE = /charset=([^()<>@,;:"/[\]?.=\s]*)/i;
@@ -35,6 +32,4 @@ export default async function renderCode(state, req, res) {
}
}
res.headers.set('content-type', contentType);
-
- contentSecurityPolicyOnCode(state, res);
}
diff --git a/src/steps/render.js b/src/steps/render.js
index 9e747187..94f5b657 100644
--- a/src/steps/render.js
+++ b/src/steps/render.js
@@ -15,7 +15,6 @@ import { h } from 'hastscript';
import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import { cleanupHeaderValue } from '@adobe/helix-shared-utils';
-import { contentSecurityPolicyOnAST } from './csp.js';
function appendElement($parent, $el) {
if ($el) {
@@ -103,7 +102,6 @@ export default async function render(state, req, res) {
const $headHtml = await unified()
.use(rehypeParse, { fragment: true })
.parse(headHtml);
- contentSecurityPolicyOnAST(res, $headHtml);
$head.children.push(...$headHtml.children);
}
diff --git a/test/fixtures/code/super-test/404-csp-nonce.html b/test/fixtures/code/super-test/404-csp-nonce.html
deleted file mode 100644
index 0b4aa8c5..00000000
--- a/test/fixtures/code/super-test/404-csp-nonce.html
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
- Page not found
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Page Not Found
-
- Go home
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/fixtures/code/super-test/404-csp-nonce.ref.html b/test/fixtures/code/super-test/404-csp-nonce.ref.html
deleted file mode 100644
index a1a238e2..00000000
--- a/test/fixtures/code/super-test/404-csp-nonce.ref.html
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
- Page not found
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Page Not Found
-
- Go home
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/fixtures/code/super-test/static-nonce-fragment.html b/test/fixtures/code/super-test/static-nonce-fragment.html
deleted file mode 100644
index c8f32793..00000000
--- a/test/fixtures/code/super-test/static-nonce-fragment.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-Nonce Test
diff --git a/test/fixtures/code/super-test/static-nonce-fragment.ref.html b/test/fixtures/code/super-test/static-nonce-fragment.ref.html
deleted file mode 100644
index 21cbd4a5..00000000
--- a/test/fixtures/code/super-test/static-nonce-fragment.ref.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-Nonce Test
diff --git a/test/fixtures/code/super-test/static-nonce-header.html b/test/fixtures/code/super-test/static-nonce-header.html
deleted file mode 100644
index dabff8fa..00000000
--- a/test/fixtures/code/super-test/static-nonce-header.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/code/super-test/static-nonce-header.ref.html b/test/fixtures/code/super-test/static-nonce-header.ref.html
deleted file mode 100644
index 5ee83800..00000000
--- a/test/fixtures/code/super-test/static-nonce-header.ref.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/code/super-test/static-nonce-meta-different.html b/test/fixtures/code/super-test/static-nonce-meta-different.html
deleted file mode 100644
index b660b86f..00000000
--- a/test/fixtures/code/super-test/static-nonce-meta-different.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/code/super-test/static-nonce-meta-different.ref.html b/test/fixtures/code/super-test/static-nonce-meta-different.ref.html
deleted file mode 100644
index b660b86f..00000000
--- a/test/fixtures/code/super-test/static-nonce-meta-different.ref.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/code/super-test/static-nonce-meta-move-as-header.html b/test/fixtures/code/super-test/static-nonce-meta-move-as-header.html
deleted file mode 100644
index 70cbe1a7..00000000
--- a/test/fixtures/code/super-test/static-nonce-meta-move-as-header.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/code/super-test/static-nonce-meta-move-as-header.ref.html b/test/fixtures/code/super-test/static-nonce-meta-move-as-header.ref.html
deleted file mode 100644
index 7a8b1c19..00000000
--- a/test/fixtures/code/super-test/static-nonce-meta-move-as-header.ref.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/code/super-test/static-nonce-meta.html b/test/fixtures/code/super-test/static-nonce-meta.html
deleted file mode 100644
index 4a3e2a06..00000000
--- a/test/fixtures/code/super-test/static-nonce-meta.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/code/super-test/static-nonce-meta.ref.html b/test/fixtures/code/super-test/static-nonce-meta.ref.html
deleted file mode 100644
index 9fb09c12..00000000
--- a/test/fixtures/code/super-test/static-nonce-meta.ref.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nonce Test
-
-
-
-
-
-
-
-
-
-
diff --git a/test/fixtures/content/nonce-headers-different.html b/test/fixtures/content/nonce-headers-different.html
deleted file mode 100644
index ce02bb02..00000000
--- a/test/fixtures/content/nonce-headers-different.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-headers-different.md b/test/fixtures/content/nonce-headers-different.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-headers-different.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/fixtures/content/nonce-headers-meta.html b/test/fixtures/content/nonce-headers-meta.html
deleted file mode 100644
index 547995dc..00000000
--- a/test/fixtures/content/nonce-headers-meta.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-headers-meta.md b/test/fixtures/content/nonce-headers-meta.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-headers-meta.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/fixtures/content/nonce-headers.html b/test/fixtures/content/nonce-headers.html
deleted file mode 100644
index f941a05b..00000000
--- a/test/fixtures/content/nonce-headers.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-headers.md b/test/fixtures/content/nonce-headers.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-headers.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/fixtures/content/nonce-meta-different.html b/test/fixtures/content/nonce-meta-different.html
deleted file mode 100644
index c5505253..00000000
--- a/test/fixtures/content/nonce-meta-different.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-meta-different.md b/test/fixtures/content/nonce-meta-different.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-meta-different.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/fixtures/content/nonce-meta-move-as-header.html b/test/fixtures/content/nonce-meta-move-as-header.html
deleted file mode 100644
index 8733139a..00000000
--- a/test/fixtures/content/nonce-meta-move-as-header.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-meta-move-as-header.md b/test/fixtures/content/nonce-meta-move-as-header.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-meta-move-as-header.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/fixtures/content/nonce-meta.html b/test/fixtures/content/nonce-meta.html
deleted file mode 100644
index f6d3289e..00000000
--- a/test/fixtures/content/nonce-meta.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-meta.md b/test/fixtures/content/nonce-meta.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-meta.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/fixtures/content/nonce-script-only.html b/test/fixtures/content/nonce-script-only.html
deleted file mode 100644
index 50b5d03c..00000000
--- a/test/fixtures/content/nonce-script-only.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-script-only.md b/test/fixtures/content/nonce-script-only.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-script-only.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/fixtures/content/nonce-style-only.html b/test/fixtures/content/nonce-style-only.html
deleted file mode 100644
index a21c0bd0..00000000
--- a/test/fixtures/content/nonce-style-only.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- ACME CORP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nonce Test
-
-
-
-
diff --git a/test/fixtures/content/nonce-style-only.md b/test/fixtures/content/nonce-style-only.md
deleted file mode 100644
index 02445e40..00000000
--- a/test/fixtures/content/nonce-style-only.md
+++ /dev/null
@@ -1 +0,0 @@
-# Nonce Test
diff --git a/test/rendering.test.js b/test/rendering.test.js
index 6ec6166a..0b1a5ee5 100644
--- a/test/rendering.test.js
+++ b/test/rendering.test.js
@@ -11,7 +11,6 @@
*/
/* eslint-env mocha */
import assert from 'assert';
-import crypto from 'crypto';
import path from 'path';
import { readFile } from 'fs/promises';
import { JSDOM } from 'jsdom';
@@ -187,14 +186,13 @@ describe('Rendering', () => {
} catch {
// ignore
}
- // console.log(expHtml);
if (!expStatus) {
// eslint-disable-next-line no-param-reassign
expStatus = expHtml === null ? 404 : 200;
}
const response = await render(url, '', expStatus, partition);
const actHtml = response.body;
- // console.log(actHtml);
+ console.log(actHtml);
if (expStatus === 200) {
const $actMain = new JSDOM(actHtml).window.document.querySelector(domSelector);
const $expMain = new JSDOM(expHtml).window.document.querySelector(domSelector);
@@ -222,36 +220,6 @@ describe('Rendering', () => {
return response;
}
- async function testRenderCode(url, expStatus = 200, spec = null, forceCompare = false) {
- if (!(url instanceof URL)) {
- // eslint-disable-next-line no-param-reassign
- url = new URL(`https://helix-pages.com/${url}`);
- }
-
- // eslint-disable-next-line no-param-reassign
- spec = spec || url.pathname.split('/').pop().split('.')[0];
- const expFile = path.resolve(__testdir, 'fixtures', 'code/super-test', `${spec}.ref.html`);
- let expHtml = null;
- try {
- expHtml = await readFile(expFile, 'utf-8');
- } catch {
- // ignore
- }
-
- const response = await render(url, '', expStatus);
- assert.strictEqual(response.status, expStatus);
- const actHtml = response.body;
- // console.log(actHtml);
- if (expStatus === 200 || forceCompare) {
- /*
- we use strict equality here because we want to ensure minimal intrusion in the customer HTML
- by the rendering pipeline. JSDOM will normalize the HTML, so we can't use it for comparison.
- */
- assert.strictEqual(actHtml, expHtml);
- }
- return response;
- }
-
describe('Section DIVS', () => {
it('renders document with 1 section correctly', async () => {
await testRender('one-section');
@@ -545,190 +513,6 @@ describe('Rendering', () => {
await testRender('head-with-script', 'html');
});
- it('renders csp nonce meta', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- head: {
- // eslint-disable-next-line quotes
- html: `\n`
- + '\n'
- + '\n'
- + '\n'
- + '\n'
- + '',
- },
- };
- const { headers } = await testRender('nonce-meta', 'html');
- assert.ok(!headers.get('content-security-policy'));
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders csp nonce headers', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- headers: {
- '/**': [
- {
- key: 'Content-Security-Policy',
- // eslint-disable-next-line quotes
- value: `script-src 'nonce-aem' 'strict-dynamic'; style-src 'nonce-aem'; base-uri 'self'; object-src 'none';`,
- },
- ],
- },
- head: {
- html: '\n'
- + '\n'
- + '\n'
- + '\n'
- + '',
- },
- };
- const { headers } = await testRender('nonce-headers', 'html');
- // eslint-disable-next-line quotes
- assert.strictEqual(headers.get('content-security-policy'), `script-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t' 'strict-dynamic'; style-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t'; base-uri 'self'; object-src 'none';`);
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders csp nonce metadata - move as header', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- head: {
- // eslint-disable-next-line quotes
- html: `\n`
- + '\n'
- + '\n'
- + '\n'
- + '\n'
- + '',
- },
- };
- const { headers } = await testRender('nonce-meta-move-as-header', 'html');
- // eslint-disable-next-line quotes
- assert.strictEqual(headers.get('content-security-policy'), `script-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t' 'strict-dynamic'; style-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t'; base-uri 'self'; object-src 'none';`);
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders csp nonce headers and metadata - move as header', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- headers: {
- '/**': [
- {
- key: 'content-security-policy',
- value: 'frame-ancestors \'self\'',
- },
- ],
- },
- head: {
- // eslint-disable-next-line quotes
- html: `\n`
- + '\n'
- + '\n'
- + '\n'
- + '\n'
- + '',
- },
- };
- const { headers } = await testRender('nonce-headers-meta', 'html');
- assert.strictEqual(headers.get('content-security-policy'), 'frame-ancestors \'self\'');
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders csp nonce script only', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- headers: {
- '/**': [
- {
- key: 'content-security-policy',
- // eslint-disable-next-line quotes
- value: `script-src 'nonce-aem' 'strict-dynamic'; base-uri 'self'; object-src 'none';`,
- },
- ],
- },
- head: {
- html: '\n'
- + '\n'
- + '\n'
- + '\n'
- + '',
- },
- };
- const { headers } = await testRender('nonce-script-only', 'html');
- // eslint-disable-next-line quotes
- assert.strictEqual(headers.get('content-security-policy'), `script-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t' 'strict-dynamic'; base-uri 'self'; object-src 'none';`);
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('does not alter csp nonce if already set to a different value by meta', async () => {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- head: {
- // eslint-disable-next-line quotes
- html: `\n`
- + '\n'
- + '\n'
- + '\n'
- + '\n'
- + '',
- },
- };
- const { headers } = await testRender('nonce-meta-different', 'html');
- assert.ok(!headers.get('content-security-policy'));
- });
-
- it('does not alter csp nonce if already set to a different value by header', async () => {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- headers: {
- '/**': [
- {
- key: 'Content-Security-Policy',
- // eslint-disable-next-line quotes
- value: `script-src 'nonce-r4nD0m' 'strict-dynamic'; style-src 'nonce-r4nD0m'; base-uri 'self'; object-src 'none';`,
- },
- ],
- },
- head: {
- html: '\n'
- + '\n'
- + '\n'
- + '\n'
- + '',
- },
- };
- const { headers } = await testRender('nonce-headers-different', 'html');
- // eslint-disable-next-line quotes
- assert.strictEqual(headers.get('content-security-policy'), `script-src 'nonce-r4nD0m' 'strict-dynamic'; style-src 'nonce-r4nD0m'; base-uri 'self'; object-src 'none';`);
- });
-
it('renders 404 if content not found', async () => {
await testRender('not-found', 'html');
// preview (code coverage)
@@ -1024,84 +808,5 @@ describe('Rendering', () => {
link: '; rel=modulepreload; as=script; crossorigin=use-credentials',
});
});
-
- it('renders static html from the codebus and applies csp from header with nonce', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- config = {
- ...DEFAULT_CONFIG,
- headers: {
- '/**': [
- {
- key: 'content-security-policy',
- // eslint-disable-next-line quotes
- value: `script-src 'nonce-aem' 'strict-dynamic'; style-src 'nonce-aem'; base-uri 'self'; object-src 'none';`,
- },
- ],
- },
- };
-
- const { headers } = await testRenderCode(new URL('https://helix-pages.com/static-nonce-header.html'));
- // eslint-disable-next-line quotes
- assert.strictEqual(headers.get('content-security-policy'), `script-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t' 'strict-dynamic'; style-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t'; base-uri 'self'; object-src 'none';`);
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders static html from the codebus and applies csp from meta with nonce', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- const { headers } = await testRenderCode(new URL('https://helix-pages.com/static-nonce-meta.html'));
- assert.ok(!headers.get('content-security-policy'));
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders static html from the codebus and applies csp from meta with nonce moved as header', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- const { headers } = await testRenderCode(new URL('https://helix-pages.com/static-nonce-meta-move-as-header.html'));
- // eslint-disable-next-line quotes
- assert.strictEqual(headers.get('content-security-policy'), `script-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t' 'strict-dynamic'; style-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t'; base-uri 'self'; object-src 'none';`);
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders static html from the codebus and applies csp with different nonce without altering', async () => {
- const { headers } = await testRenderCode(new URL('https://helix-pages.com/static-nonce-meta-different.html'));
- assert.ok(!headers.get('content-security-policy'));
- });
-
- it('renders static html from the codebus and applies csp without altering the HTML structure', async () => {
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- const { headers } = await testRenderCode(new URL('https://helix-pages.com/static-nonce-fragment.html'));
- assert.ok(!headers.get('content-security-policy'));
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
-
- it('renders 404 html from codebus and applies csp', async () => {
- loader
- .rewrite('404.html', 'super-test/404-csp-nonce.html')
- .headers('super-test/404-test.html', 'x-amz-meta-x-source-last-modified', 'Mon, 12 Oct 2009 17:50:00 GMT');
- const originalRandomBytes = crypto.randomBytes;
- try {
- crypto.randomBytes = () => Buffer.from('rA4nd0mmmrA4nd0mmm');
- const { headers } = await testRenderCode('not-found', 404, '404-csp-nonce', true);
- // eslint-disable-next-line quotes
- assert.strictEqual(headers.get('content-security-policy'), `script-src 'nonce-ckE0bmQwbW1tckE0bmQwbW1t' 'strict-dynamic'; base-uri 'self'; object-src 'none';`);
- } finally {
- crypto.randomBytes = originalRandomBytes;
- }
- });
});
});