CVE-2025-3639
Description
Liferay Portal 7.3.0 through 7.4.3.132, and Liferay DXP 2025.Q1 through 2025.Q1.6, 2024.Q4.0 through 2024.Q4.7, 2024.Q3.1 through 2024.Q3.13, 2024.Q2.0 through 2024.Q2.13, 2024.Q1.1 through 2024.Q1.15, 7.4 GA through update 92 and 7.3 GA through update 36 allows unauthenticated users with valid credentials to bypass the login process by changing the POST method to GET, once the site has MFA enabled.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.liferay.portal:release.portal.bomMaven | >= 7.3.0-ga1, <= 7.4.3.132-ga132 | — |
Affected products
1- Range: >= 7.3.0-ga1, <= 7.4.3.132-ga132
Patches
97a70daf60416LPD-52015 Update test
1 file changed · +22 −1
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web-test/src/testIntegration/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/test/LoginMVCActionCommandTest.java+22 −1 modified@@ -15,6 +15,7 @@ import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.LayoutSet; import com.liferay.portal.kernel.model.Portlet; +import com.liferay.portal.kernel.model.PortletApp; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.portlet.LiferayActionRequest; import com.liferay.portal.kernel.portlet.LiferayPortletConfig; @@ -275,7 +276,27 @@ private MockLiferayPortletActionRequest _getMockLiferayPortletActionRequest( throws Exception { MockLiferayPortletActionRequest mockLiferayPortletActionRequest = - new MockLiferayPortletActionRequest(); + new MockLiferayPortletActionRequest() { + + @Override + public Portlet getPortlet() { + return _portletLocalService.getPortletById( + LoginPortletKeys.LOGIN); + } + + @Override + public String getPortletName() { + return LoginPortletKeys.LOGIN; + } + + { + Portlet portlet = getPortlet(); + + PortletApp portletApp = portlet.getPortletApp(); + + portletApp.setSpecMajorVersion(2); + } + }; mockLiferayPortletActionRequest.setAttribute( JavaConstants.JAVAX_PORTLET_CONFIG, _getLiferayPortletConfig());
e67b47a47f3bLPD-52015 Redirect to l***n page
1 file changed · +10 −6
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web/src/main/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/LoginMVCActionCommand.java+10 −6 modified@@ -86,20 +86,24 @@ protected void doProcessAction( ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { + long companyId = _portal.getCompanyId(actionRequest); + + if (!_mfaPolicy.isMFAEnabled(companyId)) { + _loginMVCActionCommand.processAction(actionRequest, actionResponse); + + return; + } + HttpServletRequest httpServletRequest = _portal.getOriginalServletRequest( _portal.getHttpServletRequest(actionRequest)); if (AuthenticatedSessionManagerUtil.isPasswordParameterInQueryString( httpServletRequest)) { - return; - } + _postProcessAuthFailure(actionRequest, actionResponse); - long companyId = _portal.getCompanyId(actionRequest); - - if (!_mfaPolicy.isMFAEnabled(companyId)) { - _loginMVCActionCommand.processAction(actionRequest, actionResponse); + hideDefaultErrorMessage(actionRequest); return; }
1 file changed · +3 −1
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web-test/src/testIntegration/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/test/LoginMVCActionCommandTest.java+3 −1 modified@@ -209,7 +209,9 @@ HeadlessMFAChecker.class, new TrueHeadlessMFAChecker(), } @Test - public void testProcessActionWhenQueryStringContainsPwd() throws Exception { + public void testProcessActionWhenQueryStringContainsPassword() + throws Exception { + try (CompanyConfigurationTemporarySwapper configurationTemporarySwapper = new CompanyConfigurationTemporarySwapper(
d2806ad26cb1LPD-52015 Auto SF
1 file changed · +45 −45
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web-test/src/testIntegration/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/test/LoginMVCActionCommandTest.java+45 −45 modified@@ -93,51 +93,6 @@ public void setUp() throws Exception { _company = _companyLocalService.getCompany(_group.getCompanyId()); } - @Test - public void testProcessActionWhenQueryStringContainsPwd() throws Exception { - try (CompanyConfigurationTemporarySwapper - configurationTemporarySwapper = - new CompanyConfigurationTemporarySwapper( - _company.getCompanyId(), - "com.liferay.multi.factor.authentication.email.otp." + - "configuration.MFAEmailOTPConfiguration", - HashMapDictionaryBuilder.<String, Object>put( - "enabled", true - ).build()); - LogCapture logCapture = LoggerTestUtil.configureLog4JLogger( - AuthenticatedSessionManagerUtil.class.getName(), - LoggerTestUtil.WARN)) { - - MockLiferayPortletActionRequest mockLiferayPortletActionRequest = - _getMockLiferayPortletActionRequest(Collections.emptyMap()); - - MockHttpServletRequest mockHttpServletRequest = - (MockHttpServletRequest) - mockLiferayPortletActionRequest.getHttpServletRequest(); - - mockHttpServletRequest.setQueryString( - _portal.getPortletNamespace(LoginPortletKeys.LOGIN) + - "password=test"); - - _mvcActionCommand.processAction( - mockLiferayPortletActionRequest, - new MockLiferayPortletActionResponse()); - - List<LogEntry> logEntries = logCapture.getLogEntries(); - - Assert.assertEquals(logEntries.toString(), 1, logEntries.size()); - - LogEntry logEntry = logEntries.get(0); - - String logEntryMessage = logEntry.getMessage(); - - Assert.assertTrue( - logEntryMessage.contains( - "Ignoring login attempt because the password parameter " + - "was found for the request with the referer header:")); - } - } - @Test public void testProcessActionKeepsResetPasswordValueWhenItIsTrue() throws Exception { @@ -253,6 +208,51 @@ HeadlessMFAChecker.class, new TrueHeadlessMFAChecker(), } } + @Test + public void testProcessActionWhenQueryStringContainsPwd() throws Exception { + try (CompanyConfigurationTemporarySwapper + configurationTemporarySwapper = + new CompanyConfigurationTemporarySwapper( + _company.getCompanyId(), + "com.liferay.multi.factor.authentication.email.otp." + + "configuration.MFAEmailOTPConfiguration", + HashMapDictionaryBuilder.<String, Object>put( + "enabled", true + ).build()); + LogCapture logCapture = LoggerTestUtil.configureLog4JLogger( + AuthenticatedSessionManagerUtil.class.getName(), + LoggerTestUtil.WARN)) { + + MockLiferayPortletActionRequest mockLiferayPortletActionRequest = + _getMockLiferayPortletActionRequest(Collections.emptyMap()); + + MockHttpServletRequest mockHttpServletRequest = + (MockHttpServletRequest) + mockLiferayPortletActionRequest.getHttpServletRequest(); + + mockHttpServletRequest.setQueryString( + _portal.getPortletNamespace(LoginPortletKeys.LOGIN) + + "password=test"); + + _mvcActionCommand.processAction( + mockLiferayPortletActionRequest, + new MockLiferayPortletActionResponse()); + + List<LogEntry> logEntries = logCapture.getLogEntries(); + + Assert.assertEquals(logEntries.toString(), 1, logEntries.size()); + + LogEntry logEntry = logEntries.get(0); + + String logEntryMessage = logEntry.getMessage(); + + Assert.assertTrue( + logEntryMessage.contains( + "Ignoring login attempt because the password parameter " + + "was found for the request with the referer header:")); + } + } + private void _addCookieSupportCookie( MockHttpServletRequest mockHttpServletRequest) {
e4bb21b85440LPD-52015 Rename
1 file changed · +2 −2
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web-test/src/testIntegration/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/test/LoginMVCActionCommandTest.java+2 −2 modified@@ -94,7 +94,7 @@ public void setUp() throws Exception { } @Test - public void testLoginWhenQueryStringContainsPwd() throws Exception { + public void testProcessActionWhenQueryStringContainsPwd() throws Exception { try (CompanyConfigurationTemporarySwapper configurationTemporarySwapper = new CompanyConfigurationTemporarySwapper( @@ -139,7 +139,7 @@ public void testLoginWhenQueryStringContainsPwd() throws Exception { } @Test - public void testResetPasswordValueDoesNotChangeWhenItIsTrue() + public void testProcessActionKeepsResetPasswordValueWhenItIsTrue() throws Exception { User user1 = UserTestUtil.addUser(_company);
eb0457503fdbLPD-52015 Simplify test
1 file changed · +32 −66
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web-test/src/testIntegration/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/test/LoginMVCActionCommandTest.java+32 −66 modified@@ -15,7 +15,6 @@ import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.LayoutSet; import com.liferay.portal.kernel.model.Portlet; -import com.liferay.portal.kernel.model.PortletApp; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.portlet.LiferayActionRequest; import com.liferay.portal.kernel.portlet.LiferayPortletConfig; @@ -36,12 +35,14 @@ import com.liferay.portal.kernel.test.util.TestPropsValues; import com.liferay.portal.kernel.test.util.UserTestUtil; import com.liferay.portal.kernel.theme.ThemeDisplay; +import com.liferay.portal.kernel.util.HashMapBuilder; import com.liferay.portal.kernel.util.HashMapDictionaryBuilder; import com.liferay.portal.kernel.util.JavaConstants; import com.liferay.portal.kernel.util.MapUtil; import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.WebKeys; +import com.liferay.portal.security.auth.session.AuthenticatedSessionManagerUtil; import com.liferay.portal.test.log.LogCapture; import com.liferay.portal.test.log.LogEntry; import com.liferay.portal.test.log.LoggerTestUtil; @@ -53,13 +54,16 @@ import java.nio.charset.StandardCharsets; +import java.util.Collections; import java.util.List; +import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.junit.Assert; +import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; @@ -82,12 +86,15 @@ public class LoginMVCActionCommandTest { public static final AggregateTestRule aggregateTestRule = new LiferayIntegrationTestRule(); - @Test - public void testLoginWhenQueryStringContainsPwd() throws Exception { + @Before + public void setUp() throws Exception { _group = GroupTestUtil.addGroup(); _company = _companyLocalService.getCompany(_group.getCompanyId()); + } + @Test + public void testLoginWhenQueryStringContainsPwd() throws Exception { try (CompanyConfigurationTemporarySwapper configurationTemporarySwapper = new CompanyConfigurationTemporarySwapper( @@ -98,41 +105,19 @@ public void testLoginWhenQueryStringContainsPwd() throws Exception { "enabled", true ).build()); LogCapture logCapture = LoggerTestUtil.configureLog4JLogger( - "com.liferay.multi.factor.authentication.web.internal." + - "portlet.action.LoginMVCActionCommand", + AuthenticatedSessionManagerUtil.class.getName(), LoggerTestUtil.WARN)) { MockLiferayPortletActionRequest mockLiferayPortletActionRequest = - new MockLiferayPortletActionRequest() { - - @Override - public Portlet getPortlet() { - return _portletLocalService.getPortletById( - LoginPortletKeys.LOGIN); - } - - @Override - public String getPortletName() { - return LoginPortletKeys.LOGIN; - } - - { - Portlet portlet = getPortlet(); - - PortletApp portletApp = portlet.getPortletApp(); - - portletApp.setSpecMajorVersion(2); - } - }; - - mockLiferayPortletActionRequest.setAttribute( - WebKeys.THEME_DISPLAY, _getThemeDisplay()); + _getMockLiferayPortletActionRequest(Collections.emptyMap()); MockHttpServletRequest mockHttpServletRequest = (MockHttpServletRequest) mockLiferayPortletActionRequest.getHttpServletRequest(); - mockHttpServletRequest.setQueryString("_testPortlet_password=test"); + mockHttpServletRequest.setQueryString( + _portal.getPortletNamespace(LoginPortletKeys.LOGIN) + + "password=test"); _mvcActionCommand.processAction( mockLiferayPortletActionRequest, @@ -157,10 +142,6 @@ public String getPortletName() { public void testResetPasswordValueDoesNotChangeWhenItIsTrue() throws Exception { - _group = GroupTestUtil.addGroup(); - - _company = _companyLocalService.getCompany(_group.getCompanyId()); - User user1 = UserTestUtil.addUser(_company); ServiceContextThreadLocal.pushServiceContext( @@ -194,7 +175,12 @@ HeadlessMFAChecker.class, new FalseHeadlessMFAChecker(), "companyId", _company.getCompanyId())); MockLiferayPortletActionRequest mockLiferayPortletActionRequest1 = - _getMockLiferayPortletActionRequest(user1, password); + _getMockLiferayPortletActionRequest( + HashMapBuilder.put( + "login", user1.getEmailAddress() + ).put( + "password", password + ).build()); _mvcActionCommand.processAction( mockLiferayPortletActionRequest1, @@ -226,9 +212,13 @@ HeadlessMFAChecker.class, new TrueHeadlessMFAChecker(), MockLiferayPortletActionRequest mockLiferayPortletActionRequest2 = _getMockLiferayPortletActionRequest( - _getState( - (String)mockLiferayPortletActionRequest1.getAttribute( - "REDIRECT"))); + HashMapBuilder.put( + "state", + _getState( + (String) + mockLiferayPortletActionRequest1.getAttribute( + "REDIRECT")) + ).build()); HttpServletRequest httpServletRequest2 = _portal.getOriginalServletRequest( @@ -279,7 +269,7 @@ private LiferayPortletConfig _getLiferayPortletConfig() { } private MockLiferayPortletActionRequest _getMockLiferayPortletActionRequest( - String state) + Map<String, String> parameters) throws Exception { MockLiferayPortletActionRequest mockLiferayPortletActionRequest = @@ -294,34 +284,10 @@ private MockLiferayPortletActionRequest _getMockLiferayPortletActionRequest( WebKeys.COMPANY_ID, _company.getCompanyId()); mockLiferayPortletActionRequest.setAttribute( WebKeys.THEME_DISPLAY, _getThemeDisplay()); - mockLiferayPortletActionRequest.setParameter("state", state); - - _addCookieSupportCookie( - (MockHttpServletRequest) - mockLiferayPortletActionRequest.getHttpServletRequest()); - - return mockLiferayPortletActionRequest; - } - - private MockLiferayPortletActionRequest _getMockLiferayPortletActionRequest( - User user, String password) - throws Exception { - - MockLiferayPortletActionRequest mockLiferayPortletActionRequest = - new MockLiferayPortletActionRequest(); - mockLiferayPortletActionRequest.setAttribute( - JavaConstants.JAVAX_PORTLET_CONFIG, _getLiferayPortletConfig()); - mockLiferayPortletActionRequest.setAttribute( - JavaConstants.JAVAX_PORTLET_RESPONSE, - new MockLiferayPortletActionResponse()); - mockLiferayPortletActionRequest.setAttribute( - WebKeys.COMPANY_ID, _company.getCompanyId()); - mockLiferayPortletActionRequest.setAttribute( - WebKeys.THEME_DISPLAY, _getThemeDisplay()); - mockLiferayPortletActionRequest.setParameter( - "login", user.getEmailAddress()); - mockLiferayPortletActionRequest.setParameter("password", password); + parameters.forEach( + (key, value) -> mockLiferayPortletActionRequest.setParameter( + key, value)); _addCookieSupportCookie( (MockHttpServletRequest)
383a4001cfdfLPD-52015 Reuse code
2 files changed · +22 −52
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web/src/main/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/LoginMVCActionCommand.java+3 −43 modified@@ -9,8 +9,6 @@ import com.liferay.multi.factor.authentication.web.internal.constants.MFAPortletKeys; import com.liferay.multi.factor.authentication.web.internal.constants.MFAWebKeys; import com.liferay.multi.factor.authentication.web.internal.policy.MFAPolicy; -import com.liferay.petra.string.CharPool; -import com.liferay.petra.string.StringBundler; import com.liferay.portal.kernel.encryptor.Encryptor; import com.liferay.portal.kernel.exception.CompanyMaxUsersException; import com.liferay.portal.kernel.exception.CookieNotSupportedException; @@ -34,18 +32,15 @@ import com.liferay.portal.kernel.portlet.url.builder.PortletURLBuilder; import com.liferay.portal.kernel.security.auth.AuthException; import com.liferay.portal.kernel.security.auth.PrincipalException; -import com.liferay.portal.kernel.servlet.HttpHeaders; import com.liferay.portal.kernel.servlet.SessionErrors; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.Accessor; import com.liferay.portal.kernel.util.DigesterUtil; import com.liferay.portal.kernel.util.HashMapBuilder; -import com.liferay.portal.kernel.util.HttpComponentsUtil; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.kernel.util.MapUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.kernel.util.Portal; -import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.util.WebKeys; @@ -95,45 +90,10 @@ protected void doProcessAction( _portal.getOriginalServletRequest( _portal.getHttpServletRequest(actionRequest)); - String queryString = HttpComponentsUtil.getQueryString( - httpServletRequest); - - if (Validator.isNotNull(queryString) && - queryString.contains("password=")) { - - String passwordParameterName = "password="; - - String portletId = PortalUtil.getPortletId(httpServletRequest); - - if (portletId != null) { - passwordParameterName = - PortalUtil.getPortletNamespace(portletId) + - passwordParameterName; - } - - int index = queryString.indexOf(passwordParameterName); - - if ((index == 0) || - ((index > 0) && - (queryString.charAt(index - 1) == CharPool.AMPERSAND))) { - - if (_log.isWarnEnabled()) { - String referer = httpServletRequest.getHeader( - HttpHeaders.REFERER); + if (AuthenticatedSessionManagerUtil.isPasswordParameterInQueryString( + httpServletRequest)) { - _log.warn( - StringBundler.concat( - "Ignoring login attempt because the password ", - "parameter was found for the request with the ", - "referer header: ", referer)); - } - - _postProcessAuthFailure(actionRequest, actionResponse); - - hideDefaultErrorMessage(actionRequest); - - return; - } + return; } long companyId = _portal.getCompanyId(actionRequest);
portal-impl/src/com/liferay/portal/security/auth/session/AuthenticatedSessionManagerUtil.java+19 −9 modified@@ -69,14 +69,8 @@ public static long getAuthenticatedUserId( return user.getUserId(); } - public static void login( - HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse, String login, - String password, boolean rememberMe, String authType) - throws Exception { - - httpServletRequest = PortalUtil.getOriginalServletRequest( - httpServletRequest); + public static boolean isPasswordParameterInQueryString( + HttpServletRequest httpServletRequest) { String queryString = HttpComponentsUtil.getQueryString( httpServletRequest); @@ -111,10 +105,26 @@ public static void login( "referer header: ", referer)); } - return; + return true; } } + return false; + } + + public static void login( + HttpServletRequest httpServletRequest, + HttpServletResponse httpServletResponse, String login, + String password, boolean rememberMe, String authType) + throws Exception { + + httpServletRequest = PortalUtil.getOriginalServletRequest( + httpServletRequest); + + if (isPasswordParameterInQueryString(httpServletRequest)) { + return; + } + CookiesManagerUtil.validateSupportCookie(httpServletRequest); HttpSession httpSession = httpServletRequest.getSession();
a5081fefaffdLPD-52015 Add test
1 file changed · +78 −0
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web-test/src/testIntegration/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/test/LoginMVCActionCommandTest.java+78 −0 modified@@ -15,6 +15,7 @@ import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.LayoutSet; import com.liferay.portal.kernel.model.Portlet; +import com.liferay.portal.kernel.model.PortletApp; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.portlet.LiferayActionRequest; import com.liferay.portal.kernel.portlet.LiferayPortletConfig; @@ -41,6 +42,9 @@ import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.WebKeys; +import com.liferay.portal.test.log.LogCapture; +import com.liferay.portal.test.log.LogEntry; +import com.liferay.portal.test.log.LoggerTestUtil; import com.liferay.portal.test.rule.Inject; import com.liferay.portal.test.rule.LiferayIntegrationTestRule; import com.liferay.portlet.ActionRequestFactory; @@ -49,6 +53,8 @@ import java.nio.charset.StandardCharsets; +import java.util.List; + import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -76,6 +82,77 @@ public class LoginMVCActionCommandTest { public static final AggregateTestRule aggregateTestRule = new LiferayIntegrationTestRule(); + @Test + public void testLoginWhenQueryStringContainsPwd() throws Exception { + _group = GroupTestUtil.addGroup(); + + _company = _companyLocalService.getCompany(_group.getCompanyId()); + + try (CompanyConfigurationTemporarySwapper + configurationTemporarySwapper = + new CompanyConfigurationTemporarySwapper( + _company.getCompanyId(), + "com.liferay.multi.factor.authentication.email.otp." + + "configuration.MFAEmailOTPConfiguration", + HashMapDictionaryBuilder.<String, Object>put( + "enabled", true + ).build()); + LogCapture logCapture = LoggerTestUtil.configureLog4JLogger( + "com.liferay.multi.factor.authentication.web.internal." + + "portlet.action.LoginMVCActionCommand", + LoggerTestUtil.WARN)) { + + MockLiferayPortletActionRequest mockLiferayPortletActionRequest = + new MockLiferayPortletActionRequest() { + + @Override + public Portlet getPortlet() { + return _portletLocalService.getPortletById( + LoginPortletKeys.LOGIN); + } + + @Override + public String getPortletName() { + return LoginPortletKeys.LOGIN; + } + + { + Portlet portlet = getPortlet(); + + PortletApp portletApp = portlet.getPortletApp(); + + portletApp.setSpecMajorVersion(2); + } + }; + + mockLiferayPortletActionRequest.setAttribute( + WebKeys.THEME_DISPLAY, _getThemeDisplay()); + + MockHttpServletRequest mockHttpServletRequest = + (MockHttpServletRequest) + mockLiferayPortletActionRequest.getHttpServletRequest(); + + mockHttpServletRequest.setQueryString("_testPortlet_password=test"); + + _mvcActionCommand.processAction( + mockLiferayPortletActionRequest, + new MockLiferayPortletActionResponse()); + + List<LogEntry> logEntries = logCapture.getLogEntries(); + + Assert.assertEquals(logEntries.toString(), 1, logEntries.size()); + + LogEntry logEntry = logEntries.get(0); + + String logEntryMessage = logEntry.getMessage(); + + Assert.assertTrue( + logEntryMessage.contains( + "Ignoring login attempt because the password parameter " + + "was found for the request with the referer header:")); + } + } + @Test public void testResetPasswordValueDoesNotChangeWhenItIsTrue() throws Exception { @@ -281,6 +358,7 @@ private ThemeDisplay _getThemeDisplay() throws Exception { LayoutSet layoutSet = _group.getPublicLayoutSet(); + themeDisplay.setLayoutSet(layoutSet); themeDisplay.setLookAndFeel(layoutSet.getTheme(), null); themeDisplay.setPermissionChecker(
774c89c853d4LPD-52015 Abort l***n if QueryString contains pwd
1 file changed · +50 −4
modules/dxp/apps/multi-factor-authentication/multi-factor-authentication-web/src/main/java/com/liferay/multi/factor/authentication/web/internal/portlet/action/LoginMVCActionCommand.java+50 −4 modified@@ -9,6 +9,8 @@ import com.liferay.multi.factor.authentication.web.internal.constants.MFAPortletKeys; import com.liferay.multi.factor.authentication.web.internal.constants.MFAWebKeys; import com.liferay.multi.factor.authentication.web.internal.policy.MFAPolicy; +import com.liferay.petra.string.CharPool; +import com.liferay.petra.string.StringBundler; import com.liferay.portal.kernel.encryptor.Encryptor; import com.liferay.portal.kernel.exception.CompanyMaxUsersException; import com.liferay.portal.kernel.exception.CookieNotSupportedException; @@ -32,15 +34,18 @@ import com.liferay.portal.kernel.portlet.url.builder.PortletURLBuilder; import com.liferay.portal.kernel.security.auth.AuthException; import com.liferay.portal.kernel.security.auth.PrincipalException; +import com.liferay.portal.kernel.servlet.HttpHeaders; import com.liferay.portal.kernel.servlet.SessionErrors; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.Accessor; import com.liferay.portal.kernel.util.DigesterUtil; import com.liferay.portal.kernel.util.HashMapBuilder; +import com.liferay.portal.kernel.util.HttpComponentsUtil; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.kernel.util.MapUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.kernel.util.Portal; +import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.util.WebKeys; @@ -86,6 +91,51 @@ protected void doProcessAction( ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { + HttpServletRequest httpServletRequest = + _portal.getOriginalServletRequest( + _portal.getHttpServletRequest(actionRequest)); + + String queryString = HttpComponentsUtil.getQueryString( + httpServletRequest); + + if (Validator.isNotNull(queryString) && + queryString.contains("password=")) { + + String passwordParameterName = "password="; + + String portletId = PortalUtil.getPortletId(httpServletRequest); + + if (portletId != null) { + passwordParameterName = + PortalUtil.getPortletNamespace(portletId) + + passwordParameterName; + } + + int index = queryString.indexOf(passwordParameterName); + + if ((index == 0) || + ((index > 0) && + (queryString.charAt(index - 1) == CharPool.AMPERSAND))) { + + if (_log.isWarnEnabled()) { + String referer = httpServletRequest.getHeader( + HttpHeaders.REFERER); + + _log.warn( + StringBundler.concat( + "Ignoring login attempt because the password ", + "parameter was found for the request with the ", + "referer header: ", referer)); + } + + _postProcessAuthFailure(actionRequest, actionResponse); + + hideDefaultErrorMessage(actionRequest); + + return; + } + } + long companyId = _portal.getCompanyId(actionRequest); if (!_mfaPolicy.isMFAEnabled(companyId)) { @@ -105,10 +155,6 @@ protected void doProcessAction( if (!Validator.isBlank(login) && !Validator.isBlank(password)) { try { - HttpServletRequest httpServletRequest = - _portal.getOriginalServletRequest( - _portal.getHttpServletRequest(actionRequest)); - long userId = AuthenticatedSessionManagerUtil.getAuthenticatedUserId( httpServletRequest, login, password, null);
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
13- github.com/advisories/GHSA-g4wg-mpfg-x2q6ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-3639ghsaADVISORY
- github.com/liferay/liferay-portal/commit/383a4001cfdf533eb077ed6f03bc5f8fed27cf05ghsaWEB
- github.com/liferay/liferay-portal/commit/774c89c853d4b9d9abb61d6e079dab21f582cc78ghsaWEB
- github.com/liferay/liferay-portal/commit/7a70daf60416d536a45fe137d54e1054e9394fa7ghsaWEB
- github.com/liferay/liferay-portal/commit/a0265c3847af01a37d2a9ad1560e4408f2856518ghsaWEB
- github.com/liferay/liferay-portal/commit/a5081fefaffdd86a9306320c46e91f98973c39cbghsaWEB
- github.com/liferay/liferay-portal/commit/d2806ad26cb194d0c7d654f9c447857e05dd44b2ghsaWEB
- github.com/liferay/liferay-portal/commit/e4bb21b85440157b588ebbd217995113362962ccghsaWEB
- github.com/liferay/liferay-portal/commit/e67b47a47f3bccc9a85aeee6a40cd0188787aa0fghsaWEB
- github.com/liferay/liferay-portal/commit/eb0457503fdb8ac49c662b690a6a4eb139ee4c67ghsaWEB
- liferay.atlassian.net/browse/LPE-18212ghsaWEB
- liferay.dev/portal/security/known-vulnerabilities/-/asset_publisher/jekt/content/CVE-2025-3639nvdWEB
News mentions
0No linked articles in our index yet.