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,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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -723,7 +723,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
 | 
			
		|||
		return bean;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private ServletContextInitializer sessionServletRegistration() {
 | 
			
		||||
	protected final ServletContextInitializer sessionServletRegistration() {
 | 
			
		||||
		ServletRegistrationBean bean = new ServletRegistrationBean(new ExampleServlet() {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue