132 lines
7.1 KiB
Diff
132 lines
7.1 KiB
Diff
From 0410f3c4d9b39b754a2203a29834cac51da11258 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Richard=20Op=C3=A1lka?= <opalka.richard@gmail.com>
|
|
Date: Fri, 19 Jan 2024 19:52:31 +0100
|
|
Subject: [PATCH] [UNDERTOW-2264] CVE-2023-1973 Force session timeout to 2
|
|
minutes when session was created during the authentication phase. Once
|
|
authentication is complete restore original (configured) session timeout.
|
|
|
|
Signed-off-by: Flavia Rainone <frainone@redhat.com>
|
|
|
|
Origin:
|
|
https://github.com/undertow-io/undertow/commit/0410f3c4d9b39b754a2203a29834cac51da11258
|
|
---
|
|
.../impl/FormAuthenticationMechanism.java | 28 +++++++++++++++++--
|
|
.../ServletFormAuthenticationMechanism.java | 20 ++++++++++++-
|
|
2 files changed, 44 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/core/src/main/java/io/undertow/security/impl/FormAuthenticationMechanism.java b/core/src/main/java/io/undertow/security/impl/FormAuthenticationMechanism.java
|
|
index 22f95a6..5e6981e 100644
|
|
--- a/core/src/main/java/io/undertow/security/impl/FormAuthenticationMechanism.java
|
|
+++ b/core/src/main/java/io/undertow/security/impl/FormAuthenticationMechanism.java
|
|
@@ -45,9 +45,8 @@ import static io.undertow.UndertowMessages.MESSAGES;
|
|
public class FormAuthenticationMechanism implements AuthenticationMechanism {
|
|
|
|
public static final String LOCATION_ATTRIBUTE = FormAuthenticationMechanism.class.getName() + ".LOCATION";
|
|
-
|
|
public static final String DEFAULT_POST_LOCATION = "/j_security_check";
|
|
-
|
|
+ protected static final String ORIGINAL_SESSION_TIMEOUT = "io.undertow.servlet.form.auth.orig.session.timeout";;
|
|
private final String name;
|
|
private final String loginPage;
|
|
private final String errorPage;
|
|
@@ -55,6 +54,13 @@ public class FormAuthenticationMechanism implements AuthenticationMechanism {
|
|
private final FormParserFactory formParserFactory;
|
|
private final IdentityManager identityManager;
|
|
|
|
+ /**
|
|
+ * If the authentication process creates a session, this is the maximum session timeout (in seconds) during the
|
|
+ * authentication process. Once authentication is complete, the default session timeout will apply. Sessions that
|
|
+ * exist before the authentication process starts will retain their original session timeout throughout.
|
|
+ */
|
|
+ protected final int authenticationSessionTimeout = 120;
|
|
+
|
|
public FormAuthenticationMechanism(final String name, final String loginPage, final String errorPage) {
|
|
this(FormParserFactory.builder().build(), name, loginPage, errorPage);
|
|
}
|
|
@@ -144,6 +150,10 @@ public class FormAuthenticationMechanism implements AuthenticationMechanism {
|
|
protected void handleRedirectBack(final HttpServerExchange exchange) {
|
|
final Session session = Sessions.getSession(exchange);
|
|
if (session != null) {
|
|
+ final Integer originalSessionTimeout = (Integer) session.removeAttribute(ORIGINAL_SESSION_TIMEOUT);
|
|
+ if (originalSessionTimeout != null) {
|
|
+ session.setMaxInactiveInterval(originalSessionTimeout);
|
|
+ }
|
|
final String location = (String) session.removeAttribute(LOCATION_ATTRIBUTE);
|
|
if(location != null) {
|
|
exchange.addDefaultResponseListener(new DefaultResponseListener() {
|
|
@@ -179,7 +189,19 @@ public class FormAuthenticationMechanism implements AuthenticationMechanism {
|
|
}
|
|
|
|
protected void storeInitialLocation(final HttpServerExchange exchange) {
|
|
- Session session = Sessions.getOrCreateSession(exchange);
|
|
+ Session session = Sessions.getSession(exchange);
|
|
+ boolean newSession = false;
|
|
+ if (session == null) {
|
|
+ session = Sessions.getOrCreateSession(exchange);
|
|
+ newSession = true;
|
|
+ }
|
|
+ if (newSession) {
|
|
+ int originalMaxInactiveInterval = session.getMaxInactiveInterval();
|
|
+ if (originalMaxInactiveInterval > authenticationSessionTimeout) {
|
|
+ session.setAttribute(ORIGINAL_SESSION_TIMEOUT, session.getMaxInactiveInterval());
|
|
+ session.setMaxInactiveInterval(authenticationSessionTimeout);
|
|
+ }
|
|
+ }
|
|
session.setAttribute(LOCATION_ATTRIBUTE, RedirectBuilder.redirect(exchange, exchange.getRelativePath()));
|
|
}
|
|
|
|
diff --git a/servlet/src/main/java/io/undertow/servlet/handlers/security/ServletFormAuthenticationMechanism.java b/servlet/src/main/java/io/undertow/servlet/handlers/security/ServletFormAuthenticationMechanism.java
|
|
index 9c5c704..51a0b68 100644
|
|
--- a/servlet/src/main/java/io/undertow/servlet/handlers/security/ServletFormAuthenticationMechanism.java
|
|
+++ b/servlet/src/main/java/io/undertow/servlet/handlers/security/ServletFormAuthenticationMechanism.java
|
|
@@ -30,6 +30,7 @@ import io.undertow.server.session.Session;
|
|
import io.undertow.servlet.handlers.ServletRequestContext;
|
|
import io.undertow.servlet.spec.HttpSessionImpl;
|
|
import io.undertow.servlet.util.SavedRequest;
|
|
+import io.undertow.servlet.spec.ServletContextImpl;
|
|
import io.undertow.util.Headers;
|
|
import io.undertow.util.RedirectBuilder;
|
|
|
|
@@ -120,13 +121,26 @@ public class ServletFormAuthenticationMechanism extends FormAuthenticationMechan
|
|
return;
|
|
}
|
|
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
|
|
- HttpSessionImpl httpSession = servletRequestContext.getCurrentServletContext().getSession(exchange, true);
|
|
+ final ServletContextImpl servletContextImpl = servletRequestContext.getCurrentServletContext();
|
|
+ HttpSessionImpl httpSession = servletContextImpl.getSession(exchange, false);
|
|
+ boolean newSession = false;
|
|
+ if (httpSession == null) {
|
|
+ httpSession = servletContextImpl.getSession(exchange, true);
|
|
+ newSession = true;
|
|
+ }
|
|
Session session;
|
|
if (System.getSecurityManager() == null) {
|
|
session = httpSession.getSession();
|
|
} else {
|
|
session = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(httpSession));
|
|
}
|
|
+ if (newSession) {
|
|
+ int originalMaxInactiveInterval = session.getMaxInactiveInterval();
|
|
+ if (originalMaxInactiveInterval > authenticationSessionTimeout) {
|
|
+ session.setAttribute(ORIGINAL_SESSION_TIMEOUT, session.getMaxInactiveInterval());
|
|
+ session.setMaxInactiveInterval(authenticationSessionTimeout);
|
|
+ }
|
|
+ }
|
|
session.setAttribute(SESSION_KEY, RedirectBuilder.redirect(exchange, exchange.getRelativePath()));
|
|
SavedRequest.trySaveRequest(exchange);
|
|
}
|
|
@@ -143,6 +157,10 @@ public class ServletFormAuthenticationMechanism extends FormAuthenticationMechan
|
|
} else {
|
|
session = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(httpSession));
|
|
}
|
|
+ Integer originalSessionTimeout = (Integer) session.removeAttribute(ORIGINAL_SESSION_TIMEOUT);
|
|
+ if (originalSessionTimeout != null) {
|
|
+ session.setMaxInactiveInterval(originalSessionTimeout);
|
|
+ }
|
|
String path = (String) session.getAttribute(SESSION_KEY);
|
|
if (path != null) {
|
|
try {
|
|
--
|
|
2.46.2
|
|
|