Skip to content

Commit 0410f3c

Browse files
ropalkafl4via
authored andcommitted
[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 <[email protected]>
1 parent ddb4aee commit 0410f3c

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

core/src/main/java/io/undertow/security/impl/FormAuthenticationMechanism.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,22 @@
4646
public class FormAuthenticationMechanism implements AuthenticationMechanism {
4747

4848
public static final String LOCATION_ATTRIBUTE = FormAuthenticationMechanism.class.getName() + ".LOCATION";
49-
5049
public static final String DEFAULT_POST_LOCATION = "/j_security_check";
51-
50+
protected static final String ORIGINAL_SESSION_TIMEOUT = "io.undertow.servlet.form.auth.orig.session.timeout";;
5251
private final String name;
5352
private final String loginPage;
5453
private final String errorPage;
5554
private final String postLocation;
5655
private final FormParserFactory formParserFactory;
5756
private final IdentityManager identityManager;
5857

58+
/**
59+
* If the authentication process creates a session, this is the maximum session timeout (in seconds) during the
60+
* authentication process. Once authentication is complete, the default session timeout will apply. Sessions that
61+
* exist before the authentication process starts will retain their original session timeout throughout.
62+
*/
63+
protected final int authenticationSessionTimeout = 120;
64+
5965
public FormAuthenticationMechanism(final String name, final String loginPage, final String errorPage) {
6066
this(FormParserFactory.builder().build(), name, loginPage, errorPage);
6167
}
@@ -166,6 +172,10 @@ public AuthenticationMechanismOutcome runFormAuth(final HttpServerExchange excha
166172
protected void handleRedirectBack(final HttpServerExchange exchange) {
167173
final Session session = Sessions.getSession(exchange);
168174
if (session != null) {
175+
final Integer originalSessionTimeout = (Integer) session.removeAttribute(ORIGINAL_SESSION_TIMEOUT);
176+
if (originalSessionTimeout != null) {
177+
session.setMaxInactiveInterval(originalSessionTimeout);
178+
}
169179
final String location = (String) session.removeAttribute(LOCATION_ATTRIBUTE);
170180
if(location != null) {
171181
exchange.addDefaultResponseListener(new DefaultResponseListener() {
@@ -208,7 +218,19 @@ public ChallengeResult sendChallenge(final HttpServerExchange exchange, final Se
208218
}
209219

210220
protected void storeInitialLocation(final HttpServerExchange exchange) {
211-
Session session = Sessions.getOrCreateSession(exchange);
221+
Session session = Sessions.getSession(exchange);
222+
boolean newSession = false;
223+
if (session == null) {
224+
session = Sessions.getOrCreateSession(exchange);
225+
newSession = true;
226+
}
227+
if (newSession) {
228+
int originalMaxInactiveInterval = session.getMaxInactiveInterval();
229+
if (originalMaxInactiveInterval > authenticationSessionTimeout) {
230+
session.setAttribute(ORIGINAL_SESSION_TIMEOUT, session.getMaxInactiveInterval());
231+
session.setMaxInactiveInterval(authenticationSessionTimeout);
232+
}
233+
}
212234
session.setAttribute(LOCATION_ATTRIBUTE, RedirectBuilder.redirect(exchange, exchange.getRelativePath()));
213235
}
214236

servlet/src/main/java/io/undertow/servlet/handlers/security/ServletFormAuthenticationMechanism.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import io.undertow.servlet.handlers.ServletRequestContext;
3333
import io.undertow.servlet.spec.HttpSessionImpl;
3434
import io.undertow.servlet.util.SavedRequest;
35+
import io.undertow.servlet.spec.ServletContextImpl;
3536
import io.undertow.util.Headers;
3637
import io.undertow.util.RedirectBuilder;
3738

@@ -195,13 +196,26 @@ protected void storeInitialLocation(final HttpServerExchange exchange, byte[] by
195196
return;
196197
}
197198
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
198-
HttpSessionImpl httpSession = servletRequestContext.getCurrentServletContext().getSession(exchange, true);
199+
final ServletContextImpl servletContextImpl = servletRequestContext.getCurrentServletContext();
200+
HttpSessionImpl httpSession = servletContextImpl.getSession(exchange, false);
201+
boolean newSession = false;
202+
if (httpSession == null) {
203+
httpSession = servletContextImpl.getSession(exchange, true);
204+
newSession = true;
205+
}
199206
Session session;
200207
if (System.getSecurityManager() == null) {
201208
session = httpSession.getSession();
202209
} else {
203210
session = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(httpSession));
204211
}
212+
if (newSession) {
213+
int originalMaxInactiveInterval = session.getMaxInactiveInterval();
214+
if (originalMaxInactiveInterval > authenticationSessionTimeout) {
215+
session.setAttribute(ORIGINAL_SESSION_TIMEOUT, session.getMaxInactiveInterval());
216+
session.setMaxInactiveInterval(authenticationSessionTimeout);
217+
}
218+
}
205219
SessionManager manager = session.getSessionManager();
206220
if (seenSessionManagers.add(manager)) {
207221
manager.registerSessionListener(LISTENER);
@@ -226,6 +240,10 @@ protected void handleRedirectBack(final HttpServerExchange exchange) {
226240
} else {
227241
session = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(httpSession));
228242
}
243+
Integer originalSessionTimeout = (Integer) session.removeAttribute(ORIGINAL_SESSION_TIMEOUT);
244+
if (originalSessionTimeout != null) {
245+
session.setMaxInactiveInterval(originalSessionTimeout);
246+
}
229247
String path = (String) session.getAttribute(SESSION_KEY);
230248
if ((path == null || overrideInitial) && defaultPage != null) {
231249
path = defaultPage;

0 commit comments

Comments
 (0)