diff --git a/CHANGES.md b/CHANGES.md
index 147333bb3f..3144129598 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -132,6 +132,9 @@
### Build and packaging
+- Third-party libraries are updated to their latest patch and minor releases,
+ among them Struts 7.4.0, Spring 7.0.10 and Spring Security 7.1.2. OGNL is
+ pinned to 3.4.17, which fixes CVE-2026-113730.
- **The WAR no longer includes jcl-over-slf4j.** Roller logs through
commons-logging 1.4, which sends everything straight to Log4j. A deployment
that added its own commons-logging bridge should remove it.
diff --git a/app/pom.xml b/app/pom.xml
index baab64a9a9..e959000802 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -37,14 +37,14 @@ limitations under the License.
4.0.03.0.21.10.18
- 9.10.1
- 1.86
+ 9.11.1
+ 1.871.11.01.11.0
- 1.22.1
+ 1.23.01.15.0
- 3.20.0
- 1.0.0
+ 3.22.0
+ 1.1.15.0.27.0.02.26.1
@@ -54,12 +54,12 @@ limitations under the License.
1.0b31.19.02.0.20
- 7.0.9
- 7.1.1
- 7.3.0
+ 7.0.10
+ 7.1.2
+ 7.4.06.2.05.3.8
- 1.13.1
+ 1.13.22.4.11.0.23.1.3
@@ -503,7 +503,7 @@ limitations under the License.
com.fasterxml.jackson.corejackson-databind
- 2.22.3
+ 2.23.0
@@ -584,7 +584,7 @@ limitations under the License.
org.instancioinstancio-junit
- 6.0.1
+ 6.2.1test
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/head.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/head.jsp
index 5dd60291f6..6a24dd9d06 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/head.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/head.jsp
@@ -37,7 +37,7 @@ You can override it with your own file via WEB-INF/tiles-def.xml
-
+
diff --git a/app/src/test/java/org/apache/roller/weblogger/ui/WebjarPathsTest.java b/app/src/test/java/org/apache/roller/weblogger/ui/WebjarPathsTest.java
new file mode 100644
index 0000000000..f98029dd9c
--- /dev/null
+++ b/app/src/test/java/org/apache/roller/weblogger/ui/WebjarPathsTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file 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 CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.ui;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Pages load webjar files by versioned paths such as
+ * /webjars/bootstrap-icons/1.13.2/font/bootstrap-icons.css. When a
+ * webjar's version changes in the pom and a path is left behind, the server
+ * answers 404 and the page loses its styles or scripts. Every such path must
+ * name a file that a webjar on the classpath actually contains.
+ */
+public class WebjarPathsTest {
+
+ private static final Path WEBAPP = Paths.get(
+ System.getProperty("project.basedir", System.getProperty("user.dir")),
+ "src", "main", "webapp");
+
+ private static final Pattern WEBJAR_PATH = Pattern.compile("/webjars/([^'\"?#\\s]+)");
+
+ @Test
+ public void everyWebjarPathPointsAtAFileInAWebjar() throws IOException {
+ List missing = new ArrayList<>();
+ int checked = 0;
+ try (Stream files = Files.walk(WEBAPP)) {
+ for (Path file : (Iterable) files.filter(p -> p.toString().endsWith(".jsp")
+ || p.toString().endsWith(".vm"))::iterator) {
+ String text = Files.readString(file, StandardCharsets.UTF_8);
+ Matcher m = WEBJAR_PATH.matcher(text);
+ while (m.find()) {
+ checked++;
+ String resource = "META-INF/resources/webjars/" + m.group(1);
+ if (getClass().getClassLoader().getResource(resource) == null) {
+ missing.add(WEBAPP.relativize(file) + ": /webjars/" + m.group(1));
+ }
+ }
+ }
+ }
+ assertTrue(checked > 0, "no webjar paths found under " + WEBAPP);
+ assertTrue(missing.isEmpty(), "webjar files that no webjar contains:\n" + String.join("\n", missing));
+ }
+}
diff --git a/db-utils/pom.xml b/db-utils/pom.xml
index 7fa75b63cd..eb6e1da0af 100644
--- a/db-utils/pom.xml
+++ b/db-utils/pom.xml
@@ -68,7 +68,7 @@
org.apache.commonscommons-lang3
- 3.20.0
+ 3.22.0compile
diff --git a/pom.xml b/pom.xml
index 4c86cde990..9b7be5639e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,7 +41,7 @@ limitations under the License.
10.16.1.1
- 12.1.13
+ 12.1.15UTF-8UTF-87.0.0-SNAPSHOT
@@ -157,7 +157,14 @@ limitations under the License.
com.google.guavaguava
- 33.7.2-jre
+ 33.8.0-jre
+
+
+
+ ognl
+ ognl
+ 3.4.17