Skip to content

Commit 00a25f5

Browse files
committed
Don't apply CookieSameSiteSupplier to session cookies when using Jetty
Closes gh-39766
1 parent b416db4 commit 00a25f5

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import org.eclipse.jetty.server.handler.StatisticsHandler;
7878
import org.eclipse.jetty.session.DefaultSessionCache;
7979
import org.eclipse.jetty.session.FileSessionDataStore;
80+
import org.eclipse.jetty.session.SessionConfig;
8081
import org.eclipse.jetty.util.Callback;
8182
import org.eclipse.jetty.util.resource.CombinedResource;
8283
import org.eclipse.jetty.util.resource.Resource;
@@ -237,11 +238,17 @@ private Handler addHandlerWrappers(Handler handler) {
237238
handler = applyWrapper(handler, JettyHandlerWrappers.createServerHeaderHandlerWrapper(getServerHeader()));
238239
}
239240
if (!CollectionUtils.isEmpty(getCookieSameSiteSuppliers())) {
240-
handler = applyWrapper(handler, new SuppliedSameSiteCookieHandlerWrapper(getCookieSameSiteSuppliers()));
241+
handler = applyWrapper(handler,
242+
new SuppliedSameSiteCookieHandlerWrapper(getSessionCookieName(), getCookieSameSiteSuppliers()));
241243
}
242244
return handler;
243245
}
244246

247+
private String getSessionCookieName() {
248+
String name = getSession().getCookie().getName();
249+
return (name != null) ? name : SessionConfig.__DefaultSessionCookie;
250+
}
251+
245252
private Handler applyWrapper(Handler handler, Handler.Wrapper wrapper) {
246253
wrapper.setHandler(handler);
247254
return wrapper;
@@ -779,9 +786,12 @@ private static class SuppliedSameSiteCookieHandlerWrapper extends Handler.Wrappe
779786

780787
private static final SetCookieParser setCookieParser = SetCookieParser.newInstance();
781788

789+
private final String sessionCookieName;
790+
782791
private final List<CookieSameSiteSupplier> suppliers;
783792

784-
SuppliedSameSiteCookieHandlerWrapper(List<CookieSameSiteSupplier> suppliers) {
793+
SuppliedSameSiteCookieHandlerWrapper(String sessionCookieName, List<CookieSameSiteSupplier> suppliers) {
794+
this.sessionCookieName = sessionCookieName;
785795
this.suppliers = suppliers;
786796
}
787797

@@ -793,7 +803,7 @@ public boolean handle(Request request, Response response, Callback callback) thr
793803

794804
private class SuppliedSameSiteCookieResponse extends Response.Wrapper {
795805

796-
private HttpFields.Mutable wrappedHeaders;
806+
private final HttpFields.Mutable wrappedHeaders;
797807

798808
SuppliedSameSiteCookieResponse(Request request, Response wrapped) {
799809
super(request, wrapped);
@@ -825,14 +835,21 @@ public HttpField onAddField(HttpField field) {
825835

826836
private HttpField onAddSetCookieField(HttpField field) {
827837
HttpCookie cookie = setCookieParser.parse(field.getValue());
828-
SameSite sameSite = (cookie != null) ? getSameSite(cookie) : null;
838+
if (cookie == null || isSessionCookie(cookie)) {
839+
return field;
840+
}
841+
SameSite sameSite = getSameSite(cookie);
829842
if (sameSite == null) {
830843
return field;
831844
}
832845
HttpCookie updatedCookie = buildCookieWithUpdatedSameSite(cookie, sameSite);
833846
return new HttpCookieUtils.SetCookieHttpField(updatedCookie, this.compliance);
834847
}
835848

849+
private boolean isSessionCookie(HttpCookie cookie) {
850+
return SuppliedSameSiteCookieHandlerWrapper.this.sessionCookieName.equals(cookie.getName());
851+
}
852+
836853
private HttpCookie buildCookieWithUpdatedSameSite(HttpCookie cookie, SameSite sameSite) {
837854
return HttpCookie.build(cookie)
838855
.sameSite(org.eclipse.jetty.http.HttpCookie.SameSite.from(sameSite.name()))

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177
* @author Andy Wilkinson
178178
* @author Raja Kolli
179179
* @author Scott Frederick
180+
* @author Moritz Halbritter
180181
*/
181182
@SuppressWarnings("removal")
182183
@ExtendWith(OutputCaptureExtension.class)
@@ -957,6 +958,23 @@ void cookieSameSiteSuppliers() throws Exception {
957958
(header) -> assertThat(header).contains("controlled=test").contains("SameSite=Strict"));
958959
}
959960

961+
@Test
962+
void cookieSameSiteSuppliersShouldNotAffectSessionCookie() throws IOException, URISyntaxException {
963+
AbstractServletWebServerFactory factory = getFactory();
964+
factory.getSession().getCookie().setSameSite(SameSite.LAX);
965+
factory.getSession().getCookie().setName("SESSIONCOOKIE");
966+
factory.addCookieSameSiteSuppliers(CookieSameSiteSupplier.ofStrict());
967+
factory.addInitializers(new ServletRegistrationBean<>(new CookieServlet(false), "/"));
968+
this.webServer = factory.getWebServer();
969+
this.webServer.start();
970+
ClientHttpResponse clientResponse = getClientResponse(getLocalUrl("/"));
971+
assertThat(clientResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
972+
List<String> setCookieHeaders = clientResponse.getHeaders().get("Set-Cookie");
973+
assertThat(setCookieHeaders).satisfiesExactlyInAnyOrder(
974+
(header) -> assertThat(header).contains("SESSIONCOOKIE").contains("SameSite=Lax"),
975+
(header) -> assertThat(header).contains("test=test").contains("SameSite=Strict"));
976+
}
977+
960978
@Test
961979
protected void sslSessionTracking() {
962980
AbstractServletWebServerFactory factory = getFactory();
@@ -1803,7 +1821,7 @@ static final class CookieServlet extends HttpServlet {
18031821
}
18041822

18051823
@Override
1806-
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
1824+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
18071825
req.getSession(true);
18081826
resp.addCookie(new Cookie("test", "test"));
18091827
if (this.addSupplierTestCookies) {

0 commit comments

Comments
 (0)