From 1a764d9c06f2a96722c04b8d8bb1edf89e424628 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 14 Oct 2015 21:26:21 -0700 Subject: [PATCH] Default Tomcat to not save SESSIONS.ser file Update TomcatEmbeddedServletContainerFactory so that session data isn't serialized by default. Prior to this commit the SESSIONS.ser file would either be written to `/tmp` or into `baseDir` (if one was set). By not saving session data we align Tomcat with the other embedded servlet containers and reduce the risk of sensitive information being left in `/tmp`. Fixes gh-4156 --- ...TomcatEmbeddedServletContainerFactory.java | 35 +++++++++++++------ ...tEmbeddedServletContainerFactoryTests.java | 2 +- ...tEmbeddedServletContainerFactoryTests.java | 27 ++++++++++++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index 8f9c04463e..cf734863a2 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -394,18 +394,31 @@ public class TomcatEmbeddedServletContainerFactory private void configureSession(Context context) { long sessionTimeout = getSessionTimeoutInMinutes(); context.setSessionTimeout((int) sessionTimeout); + Manager manager = context.getManager(); + if (manager == null) { + manager = new StandardManager(); + context.setManager(manager); + } if (isPersistSession()) { - Manager manager = context.getManager(); - if (manager == null) { - manager = new StandardManager(); - context.setManager(manager); - } - Assert.state(manager instanceof StandardManager, - "Unable to persist HTTP session state using manager type " - + manager.getClass().getName()); - File folder = new ApplicationTemp().getFolder("tomcat-sessions"); - File file = new File(folder, "SESSIONS.ser"); - ((StandardManager) manager).setPathname(file.getAbsolutePath()); + configurePersistSession(manager); + } + else { + disablePersistSession(manager); + } + } + + private void configurePersistSession(Manager manager) { + Assert.state(manager instanceof StandardManager, + "Unable to persist HTTP session state using manager type " + + manager.getClass().getName()); + File folder = new ApplicationTemp().getFolder("tomcat-sessions"); + File file = new File(folder, "SESSIONS.ser"); + ((StandardManager) manager).setPathname(file.getAbsolutePath()); + } + + private void disablePersistSession(Manager manager) { + if (manager instanceof StandardManager) { + ((StandardManager) manager).setPathname(null); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java index a77c023991..68ac17d9f4 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java @@ -723,7 +723,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { return bean; } - private ServletContextInitializer sessionServletRegistration() { + protected final ServletContextInitializer sessionServletRegistration() { ServletRegistrationBean bean = new ServletRegistrationBean(new ExampleServlet() { @Override diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java index 515c86c1a1..311fafb1c8 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.context.embedded.tomcat; +import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; @@ -45,6 +46,7 @@ import org.springframework.util.SocketUtils; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; @@ -333,6 +335,31 @@ public class TomcatEmbeddedServletContainerFactoryTests assertForwardHeaderIsUsed(factory); } + @Test + public void disableDoesNotSaveSessionFiles() throws Exception { + File baseDir = this.temporaryFolder.newFolder(); + TomcatEmbeddedServletContainerFactory factory = getFactory(); + // If baseDir is not set SESSIONS.ser is written to a different temp folder + // each time. By setting it we can really ensure that data isn't saved + factory.setBaseDirectory(baseDir); + this.container = factory + .getEmbeddedServletContainer(sessionServletRegistration()); + this.container.start(); + String s1 = getResponse(getLocalUrl("/session")); + String s2 = getResponse(getLocalUrl("/session")); + this.container.stop(); + this.container = factory + .getEmbeddedServletContainer(sessionServletRegistration()); + this.container.start(); + String s3 = getResponse(getLocalUrl("/session")); + System.out.println(s1); + System.out.println(s2); + System.out.println(s3); + String message = "Session error s1=" + s1 + " s2=" + s2 + " s3=" + s3; + assertThat(message, s2.split(":")[0], equalTo(s1.split(":")[1])); + assertThat(message, s3.split(":")[0], not(equalTo(s2.split(":")[1]))); + } + @Override protected Wrapper getJspServlet() { Container context = ((TomcatEmbeddedServletContainer) this.container).getTomcat()