From c4a51c95829e4ff269ad87b8cfc271902e66f1d8 Mon Sep 17 00:00:00 2001 From: Susan Hert Date: Wed, 18 Jun 2025 17:32:46 -0700 Subject: [PATCH 1/3] Update to Tomcat version 10.1.42 (#1099) --- gradle.properties | 2 +- server/configs/application.properties | 5 +++ .../embedded/config/application.properties | 5 +++ .../src/org/labkey/embedded/LabKeyServer.java | 33 +++++++++++++++++++ .../LabKeyTomcatServletWebServerFactory.java | 1 + 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e7e45fe173..f8166b4b0f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -99,7 +99,7 @@ apacheDirectoryVersion=2.1.7 apacheMinaVersion=2.2.4 # Usually matches the version specified as a Spring Boot dependency (see springBootVersion below) -apacheTomcatVersion=10.1.41 +apacheTomcatVersion=10.1.42 # (mothership) -> json-path -> json-smart -> accessor-smart # (core) -> graalvm diff --git a/server/configs/application.properties b/server/configs/application.properties index 8f85e56fca..660e9d2f45 100644 --- a/server/configs/application.properties +++ b/server/configs/application.properties @@ -65,6 +65,11 @@ context.encryptionKey=@@encryptionKey@@ #context.bypass2FA=true #context.workDirLocation=/path/to/desired/workDir +## Tomcat v10.1.42 lowered the default for part count from 1000 to 10. Our default is now 500, but can be overridden here. +## Header size default changed from 10Kb to 512, which is also our default. +#context.maxConnectorPartCount=500 +#context.maxConnectorPartHeaderSize=512 + ## SMTP configuration mail.smtpHost=@@smtpHost@@ mail.smtpPort=@@smtpPort@@ diff --git a/server/configs/webapps/embedded/config/application.properties b/server/configs/webapps/embedded/config/application.properties index 62d1459fa3..7e7944c579 100644 --- a/server/configs/webapps/embedded/config/application.properties +++ b/server/configs/webapps/embedded/config/application.properties @@ -103,6 +103,11 @@ mail.smtpUser=Anonymous #context.bypass2FA=true #context.workDirLocation=@@/path/to/desired/workDir@@ +## Tomcat v10.1.42 lowered the default for part count from 1000 to 10. Our default is now 500, but can be overridden here. +## Header size default changed from 10Kb to 512, which is also our default. +#context.maxConnectorPartCount=500 +#context.maxConnectorPartHeaderSize=512 + ## Other webapps to be deployed, most commonly to deliver a set of static files. The context path to deploy into is the ## property name after the "context.additionalWebapps." prefix, and the value is the location of the webapp on disk #context.additionalWebapps.firstContextPath=@@/my/webapp/path@@ diff --git a/server/embedded/src/org/labkey/embedded/LabKeyServer.java b/server/embedded/src/org/labkey/embedded/LabKeyServer.java index 54057d5750..8668045f69 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyServer.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyServer.java @@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.ApplicationPidFileWriter; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; @@ -137,6 +138,14 @@ public WebServerFactoryCustomizer customizer() return customizer -> customizer.setDisableMBeanRegistry(false); } + @Bean + TomcatConnectorCustomizer connectorCustomizer() { + return (connector) -> { + connector.setMaxPartCount(contextSource().getMaxConnectorPartCount()); + connector.setMaxPartHeaderSize(contextSource().getMaxConnectorPartHeaderSize()); + }; + } + @Bean public TomcatServletWebServerFactory servletContainerFactory() { @@ -149,6 +158,7 @@ public TomcatServletWebServerFactory servletContainerFactory() Connector httpConnector = new Connector(); httpConnector.setScheme("http"); httpConnector.setPort(contextProperties.getHttpPort()); + result.getTomcatConnectorCustomizers().forEach(customizer -> customizer.customize(httpConnector)); result.addAdditionalTomcatConnectors(httpConnector); } @@ -446,6 +456,9 @@ public static class ContextProperties private Map>> resources; private Map additionalWebapps; + private Integer maxConnectorPartCount = 500; + private Integer maxConnectorPartHeaderSize = 512; + public List getDataSourceName() { return dataSourceName; @@ -708,6 +721,26 @@ public void setAdditionalWebapps(Map additionalWebapps) { this.additionalWebapps = additionalWebapps; } + + public Integer getMaxConnectorPartCount() + { + return maxConnectorPartCount; + } + + public void setMaxConnectorPartCount(Integer maxConnectorPartCount) + { + this.maxConnectorPartCount = maxConnectorPartCount; + } + + public Integer getMaxConnectorPartHeaderSize() + { + return maxConnectorPartHeaderSize; + } + + public void setMaxConnectorPartHeaderSize(Integer maxConnectorPartHeaderSize) + { + this.maxConnectorPartHeaderSize = maxConnectorPartHeaderSize; + } } @Configuration diff --git a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java index a02a5312e1..74cb72ff34 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java @@ -38,6 +38,7 @@ public LabKeyTomcatServletWebServerFactory(LabKeyServer server) addConnectorCustomizers(connector -> { LabKeyServer.TomcatProperties props = _server.tomcatProperties(); + _server.connectorCustomizer().customize(connector); if (props.getUseBodyEncodingForURI() != null) { From 032176fd4ecbac44d5660db4ccc5d095267423a8 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Fri, 20 Jun 2025 17:57:53 +0100 Subject: [PATCH 2/3] CSP reports don't get reported locally if using a contextPath (#1101) --- server/configs/application.properties | 1 + server/embedded/src/org/labkey/embedded/LabKeyServer.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/server/configs/application.properties b/server/configs/application.properties index 660e9d2f45..272a9f52dd 100644 --- a/server/configs/application.properties +++ b/server/configs/application.properties @@ -46,6 +46,7 @@ context.encryptionKey=@@encryptionKey@@ ## By default, we serve LabKey at the root context path (e.g. http://localhost:8080) ## You may customize the context path if you wish (e.g. http://localhost:8080/labkey) +## Context path value must start with a slash #context.contextPath=/labkey ## Using a legacy context path provides backwards compatibility with old deployments. A typical use case would be to diff --git a/server/embedded/src/org/labkey/embedded/LabKeyServer.java b/server/embedded/src/org/labkey/embedded/LabKeyServer.java index 8668045f69..69fe7bfee5 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyServer.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyServer.java @@ -94,7 +94,7 @@ public static void main(String[] args) base-uri 'self' ; frame-ancestors 'self' ; frame-src 'self' ${FRAME.SOURCES} ; - report-uri /admin-contentSecurityPolicyReport.api?cspVersion=r11&${CSP.REPORT.PARAMS} + report-uri ${context.contextPath:}/admin-contentSecurityPolicyReport.api?cspVersion=r11&${CSP.REPORT.PARAMS} """ )); application.setBannerMode(Banner.Mode.OFF); From 7710b9bd192234de1fd1c24f6c29f1028033eb82 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Sat, 21 Jun 2025 00:44:23 +0100 Subject: [PATCH 3/3] Upgrade Spring Boot and set reasonable request limits (#1104) --- gradle.properties | 4 +-- server/configs/application.properties | 11 ++++--- .../embedded/config/application.properties | 11 ++++--- .../src/org/labkey/embedded/LabKeyServer.java | 33 ------------------- .../LabKeyTomcatServletWebServerFactory.java | 1 - 5 files changed, 16 insertions(+), 44 deletions(-) diff --git a/gradle.properties b/gradle.properties index f8166b4b0f..e50b5a045b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -60,7 +60,7 @@ windowsProteomicsBinariesVersion=1.0 artifactoryPluginVersion=5.2.5 gradleNodePluginVersion=7.1.0 gradlePluginsVersion=6.1.0 -owaspDependencyCheckPluginVersion=12.1.0 +owaspDependencyCheckPluginVersion=12.1.3 versioningPluginVersion=1.1.2 # Versions of node and npm to use during the build. If set, these versions @@ -290,7 +290,7 @@ slf4jLog4jApiVersion=2.0.16 snappyJavaVersion=1.1.10.7 # Also, update apacheTomcatVersion above to match Spring Boot's Tomcat dependency version -springBootVersion=3.4.5 +springBootVersion=3.5.3 # This usually matches the Spring Framework version dictated by springBootVersion springVersion=6.2.8 diff --git a/server/configs/application.properties b/server/configs/application.properties index 272a9f52dd..d3a6a574b1 100644 --- a/server/configs/application.properties +++ b/server/configs/application.properties @@ -66,10 +66,13 @@ context.encryptionKey=@@encryptionKey@@ #context.bypass2FA=true #context.workDirLocation=/path/to/desired/workDir -## Tomcat v10.1.42 lowered the default for part count from 1000 to 10. Our default is now 500, but can be overridden here. -## Header size default changed from 10Kb to 512, which is also our default. -#context.maxConnectorPartCount=500 -#context.maxConnectorPartHeaderSize=512 +## Tomcat v10.1.42 lowered the default for part count from 1000 to 10. Our default is now 500. +## Tomcat also lowered the header size default from 10Kb to 512, which is also our default. +## We lower max connections from default 8192 to 250, providing ample concurrent requests for LabKey Server scenarios. +## These settings can be overridden if needed, but reasonable limits reduce your server's vulnerability to DoS attacks. +server.tomcat.max-part-count=500 +server.tomcat.max-part-header-size=512 +server.tomcat.max-connections=250 ## SMTP configuration mail.smtpHost=@@smtpHost@@ diff --git a/server/configs/webapps/embedded/config/application.properties b/server/configs/webapps/embedded/config/application.properties index 7e7944c579..e0e654f3bc 100644 --- a/server/configs/webapps/embedded/config/application.properties +++ b/server/configs/webapps/embedded/config/application.properties @@ -103,10 +103,13 @@ mail.smtpUser=Anonymous #context.bypass2FA=true #context.workDirLocation=@@/path/to/desired/workDir@@ -## Tomcat v10.1.42 lowered the default for part count from 1000 to 10. Our default is now 500, but can be overridden here. -## Header size default changed from 10Kb to 512, which is also our default. -#context.maxConnectorPartCount=500 -#context.maxConnectorPartHeaderSize=512 +## Tomcat v10.1.42 lowered the default for part count from 1000 to 10. Our default is now 500. +## Tomcat also lowered the header size default from 10Kb to 512, which is also our default. +## We lower max connections from default 8192 to 250, providing ample concurrent requests for LabKey Server scenarios. +## These settings can be overridden if needed, but reasonable limits reduce your server's vulnerability to DoS attacks. +server.tomcat.max-part-count=500 +server.tomcat.max-part-header-size=512 +server.tomcat.max-connections=250 ## Other webapps to be deployed, most commonly to deliver a set of static files. The context path to deploy into is the ## property name after the "context.additionalWebapps." prefix, and the value is the location of the webapp on disk diff --git a/server/embedded/src/org/labkey/embedded/LabKeyServer.java b/server/embedded/src/org/labkey/embedded/LabKeyServer.java index 69fe7bfee5..3c2fafe658 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyServer.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyServer.java @@ -7,7 +7,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.ApplicationPidFileWriter; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; @@ -138,14 +137,6 @@ public WebServerFactoryCustomizer customizer() return customizer -> customizer.setDisableMBeanRegistry(false); } - @Bean - TomcatConnectorCustomizer connectorCustomizer() { - return (connector) -> { - connector.setMaxPartCount(contextSource().getMaxConnectorPartCount()); - connector.setMaxPartHeaderSize(contextSource().getMaxConnectorPartHeaderSize()); - }; - } - @Bean public TomcatServletWebServerFactory servletContainerFactory() { @@ -158,7 +149,6 @@ public TomcatServletWebServerFactory servletContainerFactory() Connector httpConnector = new Connector(); httpConnector.setScheme("http"); httpConnector.setPort(contextProperties.getHttpPort()); - result.getTomcatConnectorCustomizers().forEach(customizer -> customizer.customize(httpConnector)); result.addAdditionalTomcatConnectors(httpConnector); } @@ -456,9 +446,6 @@ public static class ContextProperties private Map>> resources; private Map additionalWebapps; - private Integer maxConnectorPartCount = 500; - private Integer maxConnectorPartHeaderSize = 512; - public List getDataSourceName() { return dataSourceName; @@ -721,26 +708,6 @@ public void setAdditionalWebapps(Map additionalWebapps) { this.additionalWebapps = additionalWebapps; } - - public Integer getMaxConnectorPartCount() - { - return maxConnectorPartCount; - } - - public void setMaxConnectorPartCount(Integer maxConnectorPartCount) - { - this.maxConnectorPartCount = maxConnectorPartCount; - } - - public Integer getMaxConnectorPartHeaderSize() - { - return maxConnectorPartHeaderSize; - } - - public void setMaxConnectorPartHeaderSize(Integer maxConnectorPartHeaderSize) - { - this.maxConnectorPartHeaderSize = maxConnectorPartHeaderSize; - } } @Configuration diff --git a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java index 74cb72ff34..a02a5312e1 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java +++ b/server/embedded/src/org/labkey/embedded/LabKeyTomcatServletWebServerFactory.java @@ -38,7 +38,6 @@ public LabKeyTomcatServletWebServerFactory(LabKeyServer server) addConnectorCustomizers(connector -> { LabKeyServer.TomcatProperties props = _server.tomcatProperties(); - _server.connectorCustomizer().customize(connector); if (props.getUseBodyEncodingForURI() != null) {