From b848921c4470bc25bb17b02f4edec8afe0c951c0 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 29 Jan 2026 17:12:42 -0800 Subject: [PATCH 1/2] Support report-to CSP directive and Reporting-Endpoints header --- .../src/org/labkey/embedded/LabKeyServer.java | 20 +++++++++++++++++-- .../LabKeyTomcatServletWebServerFactory.java | 4 ++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/server/embedded/src/org/labkey/embedded/LabKeyServer.java b/server/embedded/src/org/labkey/embedded/LabKeyServer.java index 8e5b89e03b..50e0b450bc 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyServer.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyServer.java @@ -79,18 +79,22 @@ public static void main(String[] args) script-src 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}' ${SCRIPT.SOURCES} ; base-uri 'self' ; frame-src 'self' ${FRAME.SOURCES} ; + report-to csp-endpoint ; /* Keep in sync with ContentSecurityPolicyFilter Reporting-Endpoints header value */ """; // Add upgrade_insecure_requests substitution, frame-ancestors, and e12 version for enforce CSP String enforceCsp = baseCsp + """ ${UPGRADE.INSECURE.REQUESTS} frame-ancestors 'self' ; - report-uri ${context.contextPath:}/admin-contentSecurityPolicyReport.api?cspVersion=e12&${CSP.REPORT.PARAMS} ; + report-uri ${context.contextPath:}/admin-contentSecurityPolicyReport.api?cspVersion=e13&${CSP.REPORT.PARAMS} ; """; // Leave out upgrade_insecure_requests and frame-ancestors directives, since they produce warnings on some browsers String reportCsp = baseCsp + """ - report-uri ${context.contextPath:}/admin-contentSecurityPolicyReport.api?cspVersion=r12&${CSP.REPORT.PARAMS} ; + report-uri ${context.contextPath:}/admin-contentSecurityPolicyReport.api?cspVersion=r13&${CSP.REPORT.PARAMS} ; """; + // CSP.VERSION is substituted when ContentSecurityPolicyFilter is initialized. Value is extracted from each policy. + String cspViolationEndpoint = "${context.contextPath:}/admin-contentSecurityPolicyReportTo.api?cspVersion=${CSP.VERSION}&${CSP.REPORT.PARAMS}"; + application.setDefaultProperties(new HashMap<>() {{ // GitHub Issue 796: JSON logging stopped after Tomcat/Spring update @@ -142,6 +146,7 @@ public static void main(String[] args) put("csp.enforce", enforceCsp); put("csp.report", reportCsp); + put("csp.violation-endpoint", cspViolationEndpoint); // GitHub Issue 692: Stop using CBC in HTTPS ciphers // These settings configure HTTPS. Admins must opt in with additional settings @@ -883,6 +888,7 @@ public static class CSPFilterProperties { private String enforce; private String report; + private String violationEndpoint; public String getEnforce() { @@ -903,6 +909,16 @@ public void setReport(String report) { this.report = report; } + + public String getViolationEndpoint() + { + return violationEndpoint; + } + + public void setViolationEndpoint(String violationEndpoint) + { + this.violationEndpoint = violationEndpoint; + } } /** diff --git a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java index ba31b633ef..9fa3ab70f4 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java @@ -142,6 +142,10 @@ protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { context.addParameter("csp.report", cspFilterProperties.getReport()); } + if (cspFilterProperties.getViolationEndpoint() != null) + { + context.addParameter("csp.violationEndpoint", cspFilterProperties.getViolationEndpoint()); + } // Issue 48426: Allow config for desired work directory if (contextProperties.getWorkDirLocation() != null) From d31e4dcd3230ab165e46ee6b091c865065e31bbe Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Fri, 30 Jan 2026 13:38:52 -0800 Subject: [PATCH 2/2] Make report-to CSP directive conditional on https: being configured. Sync var names with report-to parameter names. --- .../src/org/labkey/embedded/LabKeyServer.java | 18 +----------------- .../LabKeyTomcatServletWebServerFactory.java | 4 ---- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/server/embedded/src/org/labkey/embedded/LabKeyServer.java b/server/embedded/src/org/labkey/embedded/LabKeyServer.java index 50e0b450bc..5ecfa1481f 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyServer.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyServer.java @@ -79,9 +79,8 @@ public static void main(String[] args) script-src 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}' ${SCRIPT.SOURCES} ; base-uri 'self' ; frame-src 'self' ${FRAME.SOURCES} ; - report-to csp-endpoint ; /* Keep in sync with ContentSecurityPolicyFilter Reporting-Endpoints header value */ """; - // Add upgrade_insecure_requests substitution, frame-ancestors, and e12 version for enforce CSP + // Add upgrade_insecure_requests substitution, frame-ancestors, and e13 version for enforce CSP String enforceCsp = baseCsp + """ ${UPGRADE.INSECURE.REQUESTS} frame-ancestors 'self' ; @@ -92,9 +91,6 @@ public static void main(String[] args) report-uri ${context.contextPath:}/admin-contentSecurityPolicyReport.api?cspVersion=r13&${CSP.REPORT.PARAMS} ; """; - // CSP.VERSION is substituted when ContentSecurityPolicyFilter is initialized. Value is extracted from each policy. - String cspViolationEndpoint = "${context.contextPath:}/admin-contentSecurityPolicyReportTo.api?cspVersion=${CSP.VERSION}&${CSP.REPORT.PARAMS}"; - application.setDefaultProperties(new HashMap<>() {{ // GitHub Issue 796: JSON logging stopped after Tomcat/Spring update @@ -146,7 +142,6 @@ public static void main(String[] args) put("csp.enforce", enforceCsp); put("csp.report", reportCsp); - put("csp.violation-endpoint", cspViolationEndpoint); // GitHub Issue 692: Stop using CBC in HTTPS ciphers // These settings configure HTTPS. Admins must opt in with additional settings @@ -888,7 +883,6 @@ public static class CSPFilterProperties { private String enforce; private String report; - private String violationEndpoint; public String getEnforce() { @@ -909,16 +903,6 @@ public void setReport(String report) { this.report = report; } - - public String getViolationEndpoint() - { - return violationEndpoint; - } - - public void setViolationEndpoint(String violationEndpoint) - { - this.violationEndpoint = violationEndpoint; - } } /** diff --git a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java index 9fa3ab70f4..ba31b633ef 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java @@ -142,10 +142,6 @@ protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { context.addParameter("csp.report", cspFilterProperties.getReport()); } - if (cspFilterProperties.getViolationEndpoint() != null) - { - context.addParameter("csp.violationEndpoint", cspFilterProperties.getViolationEndpoint()); - } // Issue 48426: Allow config for desired work directory if (contextProperties.getWorkDirLocation() != null)