This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/struts.git
commit 9a13f550c2f41abd5c768647a2509356915537c0 Author: Lukasz Lenart <[email protected]> AuthorDate: Sat Oct 24 09:37:21 2026 +0200 WW-5791 fix(boot): keep the base directory private and close on every start failure The filter and Tomcat are created before the base directory, so nothing can fail between creating the directory and the guarded start block. On file systems without POSIX permissions the base directory is restricted to its owner after creation. Co-Authored-By: Claude Opus 5.5 <[email protected]> --- .../org/apache/struts2/boot/StrutsBootServer.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/boot/src/main/java/org/apache/struts2/boot/StrutsBootServer.java b/boot/src/main/java/org/apache/struts2/boot/StrutsBootServer.java index 21bd6c4b6..d73b21ed7 100644 --- a/boot/src/main/java/org/apache/struts2/boot/StrutsBootServer.java +++ b/boot/src/main/java/org/apache/struts2/boot/StrutsBootServer.java @@ -31,6 +31,7 @@ import org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter; import org.apache.tomcat.util.descriptor.web.FilterDef; import org.apache.tomcat.util.descriptor.web.FilterMap; +import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.FileSystems; @@ -61,10 +62,10 @@ public final class StrutsBootServer implements AutoCloseable { } static StrutsBootServer start(ActionRegistry registry, BootSettings settings) { - Path baseDir = createBaseDir(); + CapturingStrutsFilter filter = new CapturingStrutsFilter(); Tomcat tomcat = new Tomcat(); + Path baseDir = createBaseDir(); StrutsBootServer server = new StrutsBootServer(tomcat, baseDir, settings); - CapturingStrutsFilter filter = new CapturingStrutsFilter(); try { tomcat.setBaseDir(baseDir.toString()); hideErrorReportDetails(tomcat); @@ -85,10 +86,10 @@ public final class StrutsBootServer implements AutoCloseable { ConfigurationException failure = e instanceof ConfigurationException configurationException ? configurationException : new ConfigurationException("Struts Boot failed to start: " + e.getMessage(), e); - server.closeAfterFailure(failure); + closeAfterFailure(server, failure); throw failure; } catch (Error e) { - server.closeAfterFailure(e); + closeAfterFailure(server, e); throw e; } return server; @@ -126,9 +127,9 @@ public final class StrutsBootServer implements AutoCloseable { } } - private void closeAfterFailure(Throwable failure) { + private static void closeAfterFailure(StrutsBootServer server, Throwable failure) { try { - close(); + server.close(); } catch (RuntimeException closeFailure) { failure.addSuppressed(closeFailure); } @@ -202,7 +203,12 @@ public final class StrutsBootServer implements AutoCloseable { if (FileSystems.getDefault().supportedFileAttributeViews().contains("posix")) { return Files.createTempDirectory(prefix, PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"))); } - return Files.createTempDirectory(prefix); + File dir = Files.createTempDirectory(prefix).toFile(); + if (!dir.setReadable(true, true) || !dir.setWritable(true, true) || !dir.setExecutable(true, true)) { + Files.delete(dir.toPath()); + throw new ConfigurationException("Cannot restrict the Tomcat base directory to its owner: " + dir); + } + return dir.toPath(); } catch (IOException e) { throw new ConfigurationException("Cannot create the Tomcat base directory", e); }
