VYPR
Low severityGHSA Advisory· Published Aug 18, 2025· Updated Apr 15, 2026

CVE-2025-3639

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.

PackageAffected versionsPatched versions
com.liferay.portal:release.portal.bomMaven
>= 7.3.0-ga1, <= 7.4.3.132-ga132

Affected products

1

Patches

9
7a70daf60416

LPD-52015 Update test

https://github.com/liferay/liferay-portalManuele CastroMar 27, 2025via ghsa
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());
    
e67b47a47f3b

LPD-52015 Redirect to l***n page

https://github.com/liferay/liferay-portalManuele CastroMar 27, 2025via ghsa
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;
     		}
    
a0265c3847af

LPD-52015 Rename

https://github.com/liferay/liferay-portalBrian ChanMar 27, 2025via ghsa
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(
    
d2806ad26cb1

LPD-52015 Auto SF

https://github.com/liferay/liferay-portalRafael PraxedesMar 25, 2025via ghsa
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) {
     
    
e4bb21b85440

LPD-52015 Rename

https://github.com/liferay/liferay-portalRafael PraxedesMar 25, 2025via ghsa
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);
    
eb0457503fdb

LPD-52015 Simplify test

https://github.com/liferay/liferay-portalRafael PraxedesMar 25, 2025via ghsa
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)
    
383a4001cfdf

LPD-52015 Reuse code

https://github.com/liferay/liferay-portalRafael PraxedesMar 25, 2025via ghsa
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();
    
a5081fefaffd

LPD-52015 Add test

https://github.com/liferay/liferay-portalManuele CastroMar 24, 2025via ghsa
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(
    
774c89c853d4

LPD-52015 Abort l***n if QueryString contains pwd

https://github.com/liferay/liferay-portalManuele CastroMar 24, 2025via ghsa
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

News mentions

0

No linked articles in our index yet.