From 5a981a1d7f2d2aaffbcd2f68e02206a8bdb0494b Mon Sep 17 00:00:00 2001 From: Florian Vogt Date: Wed, 1 Mar 2023 10:02:23 +0100 Subject: [PATCH] [FEATURE] CSP: Increase defaultPolicy2 to sap-target-level-3 (#580) * Enhance CSP tests * Fix assertion messages Co-authored-by: Matthias Osswald --- lib/middleware/MiddlewareManager.js | 2 +- lib/server.js | 2 +- test/lib/server/main.js | 80 ++++++++++++++----- .../server/middleware/MiddlewareManager.js | 6 +- test/lib/server/middleware/csp.js | 2 +- 5 files changed, 66 insertions(+), 26 deletions(-) diff --git a/lib/middleware/MiddlewareManager.js b/lib/middleware/MiddlewareManager.js index 7990f540..b46e2943 100644 --- a/lib/middleware/MiddlewareManager.js +++ b/lib/middleware/MiddlewareManager.js @@ -184,7 +184,7 @@ class MiddlewareManager { const defaultSAPTargetConfig = { defaultPolicy: "sap-target-level-1", defaultPolicyIsReportOnly: true, - defaultPolicy2: "sap-target-level-2", + defaultPolicy2: "sap-target-level-3", defaultPolicy2IsReportOnly: true, ignorePaths: ["test-resources/sap/ui/qunit/testrunner.html"] }; diff --git a/lib/server.js b/lib/server.js index f5780259..7c857148 100644 --- a/lib/server.js +++ b/lib/server.js @@ -99,7 +99,7 @@ async function _addSsl({app, key, cert}) { * @typedef {object} module:@ui5/server.SAPTargetCSPOptions * @property {string} [defaultPolicy="sap-target-level-1"] * @property {string} [defaultPolicyIsReportOnly=true] - * @property {string} [defaultPolicy2="sap-target-level-2"] + * @property {string} [defaultPolicy2="sap-target-level-3"] * @property {string} [defaultPolicy2IsReportOnly=true] * @property {string[]} [ignorePaths=["test-resources/sap/ui/qunit/testrunner.html"]] */ diff --git a/test/lib/server/main.js b/test/lib/server/main.js index 35d0ead4..6a8abe32 100644 --- a/test/lib/server/main.js +++ b/test/lib/server/main.js @@ -408,7 +408,7 @@ test("CSP (defaults)", async (t) => { request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-1").then((res) => { t.truthy(res.headers["content-security-policy"], "response should have enforcing csp header"); t.regex(res.headers["content-security-policy"], /script-src\s+'self'\s+'unsafe-eval'\s*;/, - "header should should have the expected content"); + "header should have the expected content"); t.is(res.headers["content-security-policy-report-only"], undefined, "response must not have report-only csp header"); }), @@ -418,12 +418,14 @@ test("CSP (defaults)", async (t) => { t.truthy(res.headers["content-security-policy-report-only"], "response should have report-only csp header"); t.regex(res.headers["content-security-policy-report-only"], /script-src\s+'self'\s+'unsafe-eval'\s*;/, - "header should should have the expected content"); + "header should have the expected content"); }), request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-2").then((res) => { t.truthy(res.headers["content-security-policy"], "response should have enforcing csp header"); t.regex(res.headers["content-security-policy"], /script-src\s+'self'\s*;/, - "header should should have the expected content"); + "header should have the expected content"); + t.regex(res.headers["content-security-policy"], /style-src\s+'self'\s+'unsafe-inline'\s*;/, + "header should have the expected content"); t.is(res.headers["content-security-policy-report-only"], undefined, "response must not have report-only csp header"); }), @@ -434,6 +436,27 @@ test("CSP (defaults)", async (t) => { "response should have report-only csp header"); t.regex(res.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, "header should have the expected content"); + t.regex(res.headers["content-security-policy-report-only"], /style-src\s+'self'\s+'unsafe-inline'\s*;/, + "header should have the expected content"); + }), + request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-3").then((res) => { + t.truthy(res.headers["content-security-policy"], "response should have enforcing csp header"); + t.regex(res.headers["content-security-policy"], /script-src\s+'self'\s*;/, + "header should have the expected content"); + t.regex(res.headers["content-security-policy"], /style-src\s+'self'\s*;/, + "header should have the expected content"); + t.is(res.headers["content-security-policy-report-only"], undefined, + "response must not have report-only csp header"); + }), + request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-3:report-only").then((res) => { + t.is(res.headers["content-security-policy"], undefined, + "response must not have enforcing csp header"); + t.truthy(res.headers["content-security-policy-report-only"], + "response should have report-only csp header"); + t.regex(res.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, + "header should have the expected content"); + t.regex(res.headers["content-security-policy-report-only"], /style-src\s+'self'\s*;/, + "header should have the expected content"); }), request.get("/index.html?sap-ui-xx-csp-policy=default-src%20http%3a;").then((res) => { t.truthy(res.headers["content-security-policy"], "response should have enforcing csp header"); @@ -480,12 +503,17 @@ test("CSP (sap policies)", async (t) => { simpleIndex: false }); - const [result1, result2, result3, result4, result5, result6, result7, result8] = await Promise.all([ + const [ + result1, result2, result3, result4, result5, + result6, result7, result8, result9, result10 + ] = await Promise.all([ request.get("/index.html"), request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-1"), request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-1:report-only"), request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-2"), request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-2:report-only"), + request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-3"), + request.get("/index.html?sap-ui-xx-csp-policy=sap-target-level-3:report-only"), request.get("/index.html?sap-ui-xx-csp-policy=default-src%20http%3a;"), request.get("/index.html?sap-ui-xx-csp-policy=default-src%20http%3a;:report-only"), request.get("/index.html?sap-ui-xx-csp-policy=default-src%20http%3a;:ro") @@ -495,13 +523,13 @@ test("CSP (sap policies)", async (t) => { t.truthy(result1.headers["content-security-policy-report-only"], "response should have report-only csp header"); t.regex(result1.headers["content-security-policy-report-only"], /script-src\s+'self'\s+'unsafe-eval'\s*;/, - "header should contain the 1st default policy"); - t.regex(result1.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, - "header should contain the 2nd default policy"); + "header should contain the 1st default policy (level-1)"); + t.regex(result1.headers["content-security-policy-report-only"], /style-src\s+'self'\s*;/, + "header should contain the 2nd default policy (level-3)"); t.truthy(result2.headers["content-security-policy"], "response should have enforcing csp header"); t.regex(result2.headers["content-security-policy"], /script-src\s+'self'\s+'unsafe-eval'\s*;/, - "header should should have the expected content"); + "header should have the expected content"); t.truthy(result2.headers["content-security-policy-report-only"], "response should have report-only csp header"); t.regex(result2.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, @@ -511,13 +539,13 @@ test("CSP (sap policies)", async (t) => { t.truthy(result3.headers["content-security-policy-report-only"], "response should have report-only csp header"); t.regex(result3.headers["content-security-policy-report-only"], /script-src\s+'self'\s+'unsafe-eval'\s*;/, - "header should should have the expected content"); + "header should have the expected content"); t.regex(result3.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, "header should contain the 2nd default policy"); t.truthy(result4.headers["content-security-policy"], "response should have enforcing csp header"); t.regex(result4.headers["content-security-policy"], /script-src\s+'self'\s*;/, - "header should should have the expected content"); + "header should have the expected content"); t.regex(result4.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, "header should contain the 2nd default policy"); @@ -528,27 +556,39 @@ test("CSP (sap policies)", async (t) => { "header should have the expected content"); t.truthy(result6.headers["content-security-policy"], "response should have enforcing csp header"); - t.regex(result6.headers["content-security-policy"], /default-src\s+http:\s*;/, - "header should contain the configured policy"); + t.regex(result6.headers["content-security-policy"], /style-src\s+'self'\s*;/, + "header should have the expected content"); t.regex(result6.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, + "header should contain the level-3 policy"); + + t.is(result7.headers["content-security-policy"], undefined, "response must not have enforcing csp header"); + t.truthy(result7.headers["content-security-policy-report-only"], + "response should have report-only csp header"); + t.regex(result7.headers["content-security-policy-report-only"], /style-src\s+'self'\s*;/, + "header should have the expected content"); + + t.truthy(result8.headers["content-security-policy"], "response should have enforcing csp header"); + t.regex(result8.headers["content-security-policy"], /default-src\s+http:\s*;/, + "header should contain the configured policy"); + t.regex(result8.headers["content-security-policy-report-only"], /script-src\s+'self'\s*;/, "header should contain the 2nd default policy"); - t.is(result7.headers["content-security-policy"], undefined, + t.is(result9.headers["content-security-policy"], undefined, "response must not have enforcing csp header"); - t.truthy(result7.headers["content-security-policy-report-only"], + t.truthy(result9.headers["content-security-policy-report-only"], "response should have report-only csp header"); - t.regex(result7.headers["content-security-policy-report-only"], /default-src\s+http:\s*;/, + t.regex(result9.headers["content-security-policy-report-only"], /default-src\s+http:\s*;/, "header should contain the configured policy"); - t.regex(result7.headers["content-security-policy-report-only"], /default-src\s+'self'\s*;/, + t.regex(result9.headers["content-security-policy-report-only"], /default-src\s+'self'\s*;/, "header should contain the 2nd default policy"); - t.is(result8.headers["content-security-policy"], undefined, + t.is(result10.headers["content-security-policy"], undefined, "response must not have enforcing csp header"); - t.truthy(result8.headers["content-security-policy-report-only"], + t.truthy(result10.headers["content-security-policy-report-only"], "response should have report-only csp header"); - t.regex(result8.headers["content-security-policy-report-only"], /default-src\s+http:\s*;/, + t.regex(result10.headers["content-security-policy-report-only"], /default-src\s+http:\s*;/, "header should contain the configured policy"); - t.regex(result8.headers["content-security-policy-report-only"], /default-src\s+'self'\s*;/, + t.regex(result10.headers["content-security-policy-report-only"], /default-src\s+'self'\s*;/, "header should contain the 2nd default policy"); await new Promise((resolve, reject) => { diff --git a/test/lib/server/middleware/MiddlewareManager.js b/test/lib/server/middleware/MiddlewareManager.js index bfa08b3e..936931a5 100644 --- a/test/lib/server/middleware/MiddlewareManager.js +++ b/test/lib/server/middleware/MiddlewareManager.js @@ -841,7 +841,7 @@ test("addStandardMiddleware: CSP middleware configured correctly (enabled)", asy }, defaultPolicy: "sap-target-level-1", defaultPolicyIsReportOnly: true, - defaultPolicy2: "sap-target-level-2", + defaultPolicy2: "sap-target-level-3", defaultPolicy2IsReportOnly: true, ignorePaths: [ "test-resources/sap/ui/qunit/testrunner.html", @@ -864,7 +864,7 @@ test("addStandardMiddleware: CSP middleware configured correctly (custom)", asyn sendSAPTargetCSP: { defaultPolicy: "sap-target-level-1", defaultPolicyIsReportOnly: false, - defaultPolicy2: "sap-target-level-3", + defaultPolicy2: "sap-target-level-2", defaultPolicy2IsReportOnly: true, ignorePaths: ["lord/tirek.html"] }, @@ -907,7 +907,7 @@ test("addStandardMiddleware: CSP middleware configured correctly (custom)", asyn }, defaultPolicy: "sap-target-level-1", defaultPolicyIsReportOnly: false, - defaultPolicy2: "sap-target-level-3", + defaultPolicy2: "sap-target-level-2", defaultPolicy2IsReportOnly: true, ignorePaths: [ "lord/tirek.html", diff --git a/test/lib/server/middleware/csp.js b/test/lib/server/middleware/csp.js index c184dbe6..b961580a 100644 --- a/test/lib/server/middleware/csp.js +++ b/test/lib/server/middleware/csp.js @@ -56,7 +56,7 @@ test("Default Settings", async (t) => { await new Promise((resolve) => { middleware({ method: "GET", - url: "/test.html?sap-ui-xx-csp-policy=sap-target-level-2", + url: "/test.html?sap-ui-xx-csp-policy=sap-target-level-3", headers: {} }, res, resolve); });