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
This commit is contained in:
		
							parent
							
								
									bbee66bac9
								
							
						
					
					
						commit
						1a764d9c06
					
				| 
						 | 
					@ -394,12 +394,20 @@ public class TomcatEmbeddedServletContainerFactory
 | 
				
			||||||
	private void configureSession(Context context) {
 | 
						private void configureSession(Context context) {
 | 
				
			||||||
		long sessionTimeout = getSessionTimeoutInMinutes();
 | 
							long sessionTimeout = getSessionTimeoutInMinutes();
 | 
				
			||||||
		context.setSessionTimeout((int) sessionTimeout);
 | 
							context.setSessionTimeout((int) sessionTimeout);
 | 
				
			||||||
		if (isPersistSession()) {
 | 
					 | 
				
			||||||
		Manager manager = context.getManager();
 | 
							Manager manager = context.getManager();
 | 
				
			||||||
		if (manager == null) {
 | 
							if (manager == null) {
 | 
				
			||||||
			manager = new StandardManager();
 | 
								manager = new StandardManager();
 | 
				
			||||||
			context.setManager(manager);
 | 
								context.setManager(manager);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (isPersistSession()) {
 | 
				
			||||||
 | 
								configurePersistSession(manager);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								disablePersistSession(manager);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void configurePersistSession(Manager manager) {
 | 
				
			||||||
		Assert.state(manager instanceof StandardManager,
 | 
							Assert.state(manager instanceof StandardManager,
 | 
				
			||||||
				"Unable to persist HTTP session state using manager type "
 | 
									"Unable to persist HTTP session state using manager type "
 | 
				
			||||||
						+ manager.getClass().getName());
 | 
											+ manager.getClass().getName());
 | 
				
			||||||
| 
						 | 
					@ -407,6 +415,11 @@ public class TomcatEmbeddedServletContainerFactory
 | 
				
			||||||
		File file = new File(folder, "SESSIONS.ser");
 | 
							File file = new File(folder, "SESSIONS.ser");
 | 
				
			||||||
		((StandardManager) manager).setPathname(file.getAbsolutePath());
 | 
							((StandardManager) manager).setPathname(file.getAbsolutePath());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void disablePersistSession(Manager manager) {
 | 
				
			||||||
 | 
							if (manager instanceof StandardManager) {
 | 
				
			||||||
 | 
								((StandardManager) manager).setPathname(null);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private long getSessionTimeoutInMinutes() {
 | 
						private long getSessionTimeoutInMinutes() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -723,7 +723,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
 | 
				
			||||||
		return bean;
 | 
							return bean;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private ServletContextInitializer sessionServletRegistration() {
 | 
						protected final ServletContextInitializer sessionServletRegistration() {
 | 
				
			||||||
		ServletRegistrationBean bean = new ServletRegistrationBean(new ExampleServlet() {
 | 
							ServletRegistrationBean bean = new ServletRegistrationBean(new ExampleServlet() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			@Override
 | 
								@Override
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package org.springframework.boot.context.embedded.tomcat;
 | 
					package org.springframework.boot.context.embedded.tomcat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.net.InetSocketAddress;
 | 
					import java.net.InetSocketAddress;
 | 
				
			||||||
import java.net.ServerSocket;
 | 
					import java.net.ServerSocket;
 | 
				
			||||||
| 
						 | 
					@ -45,6 +46,7 @@ import org.springframework.util.SocketUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.hamcrest.Matchers.equalTo;
 | 
					import static org.hamcrest.Matchers.equalTo;
 | 
				
			||||||
import static org.hamcrest.Matchers.is;
 | 
					import static org.hamcrest.Matchers.is;
 | 
				
			||||||
 | 
					import static org.hamcrest.Matchers.not;
 | 
				
			||||||
import static org.junit.Assert.assertEquals;
 | 
					import static org.junit.Assert.assertEquals;
 | 
				
			||||||
import static org.junit.Assert.assertFalse;
 | 
					import static org.junit.Assert.assertFalse;
 | 
				
			||||||
import static org.junit.Assert.assertThat;
 | 
					import static org.junit.Assert.assertThat;
 | 
				
			||||||
| 
						 | 
					@ -333,6 +335,31 @@ public class TomcatEmbeddedServletContainerFactoryTests
 | 
				
			||||||
		assertForwardHeaderIsUsed(factory);
 | 
							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
 | 
						@Override
 | 
				
			||||||
	protected Wrapper getJspServlet() {
 | 
						protected Wrapper getJspServlet() {
 | 
				
			||||||
		Container context = ((TomcatEmbeddedServletContainer) this.container).getTomcat()
 | 
							Container context = ((TomcatEmbeddedServletContainer) this.container).getTomcat()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue