VYPR
Moderate severityNVD Advisory· Published Aug 22, 2025· Updated Aug 22, 2025

CVE-2025-43751

CVE-2025-43751

Description

User enumeration vulnerability in Liferay Portal 7.4.0 through 7.4.3.132, and Liferay DXP 2024.Q4.0 through 2024.Q4.7, 2024.Q3.0 through 2024.Q3.13, 2024.Q2.0 through 2024.Q2.13, 2024.Q1.1 through 2024.Q1.14, 2023.Q4.0 through 2023.Q4.10, 2023.Q3.1 through 2023.Q3.10 and 7.4 GA through update 92 allows remote attackers to determine if an account exist in the application via the create account page.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
com.liferay:com.liferay.login.webMaven
< 6.0.666.0.66

Affected products

2

Patches

8
4987ff8641b9

LPD-44960 Auto SF

https://github.com/liferay/liferay-portalBrian ChanJan 21, 2025via ghsa
1 file changed · +17 16
  • modules/apps/login/login-web/src/main/java/com/liferay/login/web/internal/portlet/action/CreateAccountMVCActionCommand.java+17 16 modified
    @@ -346,7 +346,8 @@ else if (exception instanceof
     			}
     		}
     
    -		_sendCompanySecurityStrangersURLRedirect(actionRequest, actionResponse, themeDisplay);
    +		_sendCompanySecurityStrangersURLRedirect(
    +			actionRequest, actionResponse, themeDisplay);
     	}
     
     	protected CaptchaConfiguration getCaptchaConfiguration()
    @@ -555,21 +556,6 @@ private void _resetUser(
     		addUser(actionRequest, actionResponse);
     	}
     
    -	private void _updateUserAndSendRedirect(
    -			ActionRequest actionRequest, ActionResponse actionResponse,
    -			ThemeDisplay themeDisplay, User user, String password1)
    -		throws Exception {
    -
    -		_userLocalService.updateLastLogin(user.getUserId(), user.getLoginIP());
    -
    -		_userLocalService.updatePasswordReset(user.getUserId(), false);
    -
    -		_userLocalService.updateEmailAddressVerified(user.getUserId(), true);
    -
    -		sendRedirect(
    -			actionRequest, actionResponse, themeDisplay, user, password1);
    -	}
    -
     	private void _sendCompanySecurityStrangersURLRedirect(
     			ActionRequest actionRequest, ActionResponse actionResponse,
     			ThemeDisplay themeDisplay)
    @@ -598,6 +584,21 @@ private void _sendCompanySecurityStrangersURLRedirect(
     		}
     	}
     
    +	private void _updateUserAndSendRedirect(
    +			ActionRequest actionRequest, ActionResponse actionResponse,
    +			ThemeDisplay themeDisplay, User user, String password1)
    +		throws Exception {
    +
    +		_userLocalService.updateLastLogin(user.getUserId(), user.getLoginIP());
    +
    +		_userLocalService.updatePasswordReset(user.getUserId(), false);
    +
    +		_userLocalService.updateEmailAddressVerified(user.getUserId(), true);
    +
    +		sendRedirect(
    +			actionRequest, actionResponse, themeDisplay, user, password1);
    +	}
    +
     	private ActionRequest _wrapActionRequest(ActionRequest actionRequest)
     		throws Exception {
     
    
1205e7bbcc31

LPD-44960 Rename

https://github.com/liferay/liferay-portalBrian ChanJan 21, 2025via ghsa
1 file changed · +3 3
  • modules/apps/login/login-web/src/main/java/com/liferay/login/web/internal/portlet/action/CreateAccountMVCActionCommand.java+3 3 modified
    @@ -286,7 +286,7 @@ else if (user.getStatus() ==
     					actionRequest, actionResponse, themeDisplay, user,
     					user.getPasswordUnencrypted());
     
    -				_verifyStrangersURL(
    +				_sendCompanySecurityStrangersURLRedirect(
     					actionRequest, actionResponse, themeDisplay);
     
     				return;
    @@ -346,7 +346,7 @@ else if (exception instanceof
     			}
     		}
     
    -		_verifyStrangersURL(actionRequest, actionResponse, themeDisplay);
    +		_sendCompanySecurityStrangersURLRedirect(actionRequest, actionResponse, themeDisplay);
     	}
     
     	protected CaptchaConfiguration getCaptchaConfiguration()
    @@ -570,7 +570,7 @@ private void _updateUserAndSendRedirect(
     			actionRequest, actionResponse, themeDisplay, user, password1);
     	}
     
    -	private void _verifyStrangersURL(
    +	private void _sendCompanySecurityStrangersURLRedirect(
     			ActionRequest actionRequest, ActionResponse actionResponse,
     			ThemeDisplay themeDisplay)
     		throws Exception {
    
7e9e29a9dac8

LPD-44960 Don't add SessionError when email address is duplicate

https://github.com/liferay/liferay-portalRafael PraxedesJan 18, 2025via ghsa
1 file changed · +5 0
  • modules/apps/login/login-web/src/main/java/com/liferay/login/web/internal/portlet/action/CreateAccountMVCActionCommand.java+5 0 modified
    @@ -285,6 +285,11 @@ else if (user.getStatus() ==
     				sendRedirect(
     					actionRequest, actionResponse, themeDisplay, user,
     					user.getPasswordUnencrypted());
    +
    +				_verifyStrangersURL(
    +					actionRequest, actionResponse, themeDisplay);
    +
    +				return;
     			}
     			else if (exception instanceof
     						UserScreenNameException.MustNotBeDuplicate) {
    
097597e31b59

LPD-44960 Extract method that verify the PropsValues.COMPANY_SECURITY_STRANGERS_URL property

https://github.com/liferay/liferay-portalRafael PraxedesJan 18, 2025via ghsa
1 file changed · +29 21
  • modules/apps/login/login-web/src/main/java/com/liferay/login/web/internal/portlet/action/CreateAccountMVCActionCommand.java+29 21 modified
    @@ -341,27 +341,7 @@ else if (exception instanceof
     			}
     		}
     
    -		if (Validator.isNull(PropsValues.COMPANY_SECURITY_STRANGERS_URL)) {
    -			return;
    -		}
    -
    -		try {
    -			Layout layout = _layoutLocalService.getFriendlyURLLayout(
    -				themeDisplay.getScopeGroupId(), false,
    -				PropsValues.COMPANY_SECURITY_STRANGERS_URL);
    -
    -			String redirect = _portal.getLayoutURL(layout, themeDisplay);
    -
    -			sendRedirect(actionRequest, actionResponse, redirect);
    -		}
    -		catch (NoSuchLayoutException noSuchLayoutException) {
    -
    -			// LPS-52675
    -
    -			if (_log.isDebugEnabled()) {
    -				_log.debug(noSuchLayoutException);
    -			}
    -		}
    +		_verifyStrangersURL(actionRequest, actionResponse, themeDisplay);
     	}
     
     	protected CaptchaConfiguration getCaptchaConfiguration()
    @@ -585,6 +565,34 @@ private void _updateUserAndSendRedirect(
     			actionRequest, actionResponse, themeDisplay, user, password1);
     	}
     
    +	private void _verifyStrangersURL(
    +			ActionRequest actionRequest, ActionResponse actionResponse,
    +			ThemeDisplay themeDisplay)
    +		throws Exception {
    +
    +		if (Validator.isNull(PropsValues.COMPANY_SECURITY_STRANGERS_URL)) {
    +			return;
    +		}
    +
    +		try {
    +			Layout layout = _layoutLocalService.getFriendlyURLLayout(
    +				themeDisplay.getScopeGroupId(), false,
    +				PropsValues.COMPANY_SECURITY_STRANGERS_URL);
    +
    +			String redirect = _portal.getLayoutURL(layout, themeDisplay);
    +
    +			sendRedirect(actionRequest, actionResponse, redirect);
    +		}
    +		catch (NoSuchLayoutException noSuchLayoutException) {
    +
    +			// LPS-52675
    +
    +			if (_log.isDebugEnabled()) {
    +				_log.debug(noSuchLayoutException);
    +			}
    +		}
    +	}
    +
     	private ActionRequest _wrapActionRequest(ActionRequest actionRequest)
     		throws Exception {
     
    
4f3b52bc9287

LPD-44960 Refactor and add new test case

https://github.com/liferay/liferay-portalManuele CastroJan 17, 2025via ghsa
3 files changed · +183 37
  • modules/test/playwright/pages/captcha-web/CaptchaConfigPage.ts+63 10 modified
    @@ -5,11 +5,13 @@
     
     import {Locator, Page, expect} from '@playwright/test';
     
    +import {clickAndExpectToBeVisible} from '../../utils/clickAndExpectToBeVisible';
     import {waitForAlert} from '../../utils/waitForAlert';
     import {ApplicationsMenuPage} from '../product-navigation-applications-menu/ApplicationsMenuPage';
     
     export class CaptchaConfigPage {
     	readonly applicationsMenuPage: ApplicationsMenuPage;
    +	readonly actions: Locator;
     	readonly captchaEngine: Locator;
     	readonly createAccountCaptchaEnabled: Locator;
     	readonly maxChallenges: Locator;
    @@ -21,6 +23,7 @@ export class CaptchaConfigPage {
     	readonly reCaptchaPublicKey: Locator;
     	readonly reCaptchaScriptURL: Locator;
     	readonly reCaptchaVerifyURL: Locator;
    +	readonly resetDefaultValues: Locator;
     	readonly saveButton: Locator;
     	readonly sendPasswordCaptchaEnabled: Locator;
     	readonly simpleCaptchaHeight: Locator;
    @@ -29,6 +32,7 @@ export class CaptchaConfigPage {
     
     	constructor(page: Page) {
     		this.applicationsMenuPage = new ApplicationsMenuPage(page);
    +		this.actions = page.getByRole('button', {name: 'Actions'});
     		this.captchaEngine = page.getByLabel('CAPTCHA Engine');
     		this.createAccountCaptchaEnabled = page.getByText(
     			'Create Account CAPTCHA Enabled'
    @@ -46,6 +50,9 @@ export class CaptchaConfigPage {
     		this.reCaptchaPublicKey = page.getByLabel('reCAPTCHA Public Key');
     		this.reCaptchaScriptURL = page.getByLabel('reCAPTCHA Script URL');
     		this.reCaptchaVerifyURL = page.getByLabel('reCAPTCHA Verify URL');
    +		this.resetDefaultValues = page.getByRole('link', {
    +			name: 'Reset Default Values',
    +		});
     		this.saveButton = page.getByRole('button', {name: 'Save'});
     		this.sendPasswordCaptchaEnabled = page.getByText(
     			'Send Password CAPTCHA Enabled'
    @@ -60,49 +67,76 @@ export class CaptchaConfigPage {
     
     		await this.maxChallenges.fill('-1');
     
    -		await this.disableCreateAccountCaptcha();
    +		await this.disableCreateAccountCaptcha(false);
     
    -		await this.disableSendPasswordCaptcha();
    +		await this.disableSendPasswordCaptcha(false);
     
    -		await this.disableMessageBoardsEditCategoryCaptcha();
    +		await this.disableMessageBoardsEditCategoryCaptcha(false);
     
    -		await this.disableMessageBoardsEditMessageCaptcha();
    +		await this.disableMessageBoardsEditMessageCaptcha(false);
     
     		await this.saveConfiguration();
     	}
     
    -	async disableCreateAccountCaptcha() {
    +	async disableCreateAccountCaptcha(saveConfiguration: boolean = true) {
     		await this.createAccountCaptchaEnabled.uncheck();
     		await expect(this.createAccountCaptchaEnabled).not.toBeChecked();
    +
    +		if (saveConfiguration) {
    +			await this.saveConfiguration();
    +		}
     	}
     
    -	async disableMessageBoardsEditCategoryCaptcha() {
    +	async disableMessageBoardsEditCategoryCaptcha(
    +		saveConfiguration: boolean = true
    +	) {
     		await this.messageBoardsEditCategoryCaptchaEnabled.uncheck();
     		await expect(
     			this.messageBoardsEditCategoryCaptchaEnabled
     		).not.toBeChecked();
    +
    +		if (saveConfiguration) {
    +			await this.saveConfiguration();
    +		}
     	}
     
    -	async disableMessageBoardsEditMessageCaptcha() {
    +	async disableMessageBoardsEditMessageCaptcha(
    +		saveConfiguration: boolean = true
    +	) {
     		await this.messageBoardsEditMessageCaptchaEnabled.uncheck();
     		await expect(
     			this.messageBoardsEditMessageCaptchaEnabled
     		).not.toBeChecked();
    +
    +		if (saveConfiguration) {
    +			await this.saveConfiguration();
    +		}
     	}
     
    -	async disableSendPasswordCaptcha() {
    +	async disableSendPasswordCaptcha(saveConfiguration: boolean = true) {
     		await this.sendPasswordCaptchaEnabled.uncheck();
     		await expect(this.sendPasswordCaptchaEnabled).not.toBeChecked();
    +
    +		if (saveConfiguration) {
    +			await this.saveConfiguration();
    +		}
     	}
     
    -	async enableReCaptcha(publicKey: string, privateKey: string) {
    +	async enableReCaptcha(
    +		publicKey: string,
    +		privateKey: string,
    +		saveConfiguration: boolean = true
    +	) {
     		await this.captchaEngine.click();
    -
     		await this.page.getByRole('option', {name: 'reCAPTCHA'}).click();
     
     		await this.reCaptchaPublicKey.fill(publicKey);
     
     		await this.reCaptchaPrivateKey.fill(privateKey);
    +
    +		if (saveConfiguration) {
    +			await this.saveConfiguration();
    +		}
     	}
     
     	async goTo() {
    @@ -113,10 +147,29 @@ export class CaptchaConfigPage {
     		await this.sendPasswordCaptchaEnabled.waitFor();
     	}
     
    +	async resetCaptchaConfiguration() {
    +		if (await this.actions.isVisible()) {
    +			await clickAndExpectToBeVisible({
    +				autoClick: true,
    +				target: this.resetDefaultValues,
    +				trigger: this.actions,
    +			});
    +
    +			await waitForAlert(this.page);
    +
    +			await this.saveConfiguration();
    +		}
    +	}
    +
     	async saveConfiguration() {
     		if (await this.page.isVisible('button:has-text("Update")')) {
     			await this.updateButton.click();
     
    +			await waitForAlert(
    +				this.page,
    +				`Success:Your request completed successfully.`
    +			);
    +
     			return;
     		}
     
    
  • modules/test/playwright/tests/captcha-web/recaptcha.spec.ts+0 1 modified
    @@ -22,7 +22,6 @@ test('LPD-32888 Check reCaptcha has a label for textarea', async ({
     		reCaptchaConfig.publicKey,
     		reCaptchaConfig.privateKey
     	);
    -	await captchaConfigPage.saveConfiguration();
     
     	await performLogout(page);
     	await page.goto(liferayConfig.environment.baseUrl);
    
  • modules/test/playwright/tests/login-web/createAccount.spec.ts+120 26 modified
    @@ -6,54 +6,148 @@
     import {expect, mergeTests} from '@playwright/test';
     
     import {captchaConfigPageTest} from '../../fixtures/captchaConfigPageTest';
    +import {instanceSettingsPagesTest} from '../../fixtures/instanceSettingsPagesTest';
     import {loginTest} from '../../fixtures/loginTest';
     import {liferayConfig} from '../../liferay.config';
     import getRandomString from '../../utils/getRandomString';
    -import {performLogout} from '../../utils/performLogin';
    +import performLogin, {performLogout} from '../../utils/performLogin';
     
    -export const test = mergeTests(loginTest(), captchaConfigPageTest);
    +export const test = mergeTests(
    +	captchaConfigPageTest,
    +	instanceSettingsPagesTest,
    +	loginTest()
    +);
    +
    +test.beforeEach(
    +	'Disable create account CAPTCHA',
    +	async ({captchaConfigPage, page}) => {
    +		await page.goto(liferayConfig.environment.baseUrl);
    +
    +		if (await page.getByRole('button', {name: 'Sign In'}).isVisible()) {
    +			await performLogin(page, 'test');
    +		}
     
    -test.describe('Duplicate account creation', () => {
    -	test('Using already existing email address does not throw failure alert', async ({
    -		captchaConfigPage,
    -		page,
    -	}) => {
     		await captchaConfigPage.goTo();
     
     		await captchaConfigPage.disableCreateAccountCaptcha();
    +	}
    +);
    +
    +test.afterEach(
    +	'Reset CAPTCHA configuration',
    +	async ({captchaConfigPage, page}) => {
    +		await page.goto(liferayConfig.environment.baseUrl);
    +
    +		if (await page.getByRole('button', {name: 'Sign In'}).isVisible()) {
    +			await performLogin(page, 'test');
    +		}
     
    -		await captchaConfigPage.saveConfiguration();
    +		await captchaConfigPage.goTo();
     
    -		await performLogout(page);
    +		await captchaConfigPage.resetCaptchaConfiguration();
     
     		await page.goto(liferayConfig.environment.baseUrl);
    +	}
    +);
    +
    +test('LPD-44960 Create account using duplicate email address', async ({
    +	page,
    +}) => {
    +	await performLogout(page);
    +
    +	await page.goto(liferayConfig.environment.baseUrl);
    +
    +	await page.getByRole('button', {name: 'Sign In'}).click();
    +
    +	await page.getByText('Create Account').click();
    +
    +	await page.getByLabel('Screen Name').fill(getRandomString());
    +
    +	await page.getByLabel('Email Address').fill('test@liferay.com');
    +
    +	await page.getByLabel('First Name').fill(getRandomString());
    +
    +	await page.getByLabel('Last Name').fill(getRandomString());
    +
    +	const password = getRandomString();
    +
    +	await page.getByLabel('Password Required', {exact: true}).fill(password);
    +
    +	await page.getByLabel('Reenter Password Required').fill(password);
    +
    +	await page.getByRole('button', {name: 'Save'}).click();
    +
    +	await expect(
    +		page.getByText(
    +			'Thank you for creating an account. Use your password to log in.'
    +		)
    +	).toBeVisible();
    +
    +	await expect(
    +		page.getByText('Error:Your request failed to complete.')
    +	).toBeHidden();
    +});
    +
    +test('LPD-44960 Create account using duplicate email address with email address verification', async ({
    +	instanceSettingsPage,
    +	page,
    +}) => {
    +	await instanceSettingsPage.goToInstanceSetting(
    +		'User Authentication',
    +		'General'
    +	);
    +
    +	const strangersVerify = page.getByText(
    +		'Require strangers to verify their email address?'
    +	);
    +	await strangersVerify.check();
    +	await expect(strangersVerify).toBeChecked();
    +
    +	await instanceSettingsPage.saveAndWaitForAlert();
    +
    +	await performLogout(page);
    +
    +	await page.goto(liferayConfig.environment.baseUrl);
    +
    +	await page.getByRole('button', {name: 'Sign In'}).click();
    +
    +	await page.getByText('Create Account').click();
    +
    +	await page.getByLabel('Screen Name').fill(getRandomString());
    +
    +	await page.getByLabel('Email Address').fill('test@liferay.com');
     
    -		await page.getByRole('button', {name: 'Sign In'}).click();
    +	await page.getByLabel('First Name').fill(getRandomString());
     
    -		await page.getByText('Create Account').click();
    +	await page.getByLabel('Last Name').fill(getRandomString());
     
    -		await page.getByLabel('Screen Name').fill(getRandomString());
    +	const password = getRandomString();
     
    -		await page.getByLabel('Email Address').fill('test@liferay.com');
    +	await page.getByLabel('Password Required', {exact: true}).fill(password);
     
    -		await page.getByLabel('First Name').fill(getRandomString());
    +	await page.getByLabel('Reenter Password Required').fill(password);
     
    -		await page.getByLabel('Last Name').fill(getRandomString());
    +	await page.getByRole('button', {name: 'Save'}).click();
     
    -		const password = getRandomString();
    +	await expect(
    +		page.getByText(
    +			'Thank you for creating an account. Your email verification code was sent to test@liferay.com. Use your password to log in.'
    +		)
    +	).toBeVisible();
     
    -		await page
    -			.getByLabel('Password Required', {exact: true})
    -			.fill(password);
    +	await expect(
    +		page.getByText('Error:Your request failed to complete.')
    +	).toBeHidden();
     
    -		await page.getByLabel('Reenter Password Required').fill(password);
    +	await performLogin(page, 'test');
     
    -		await page.getByRole('button', {name: 'Save'}).click();
    +	await instanceSettingsPage.goToInstanceSetting(
    +		'User Authentication',
    +		'General'
    +	);
     
    -		await page.waitForTimeout(1000);
    +	await strangersVerify.uncheck();
    +	await expect(strangersVerify).not.toBeChecked();
     
    -		await expect(
    -			page.getByText('Error:Your request failed to complete.')
    -		).toBeHidden({timeout: 500});
    -	});
    +	await instanceSettingsPage.saveAndWaitForAlert();
     });
    
4843e000995e

LPD-44960 Add create account test

https://github.com/liferay/liferay-portalManuele CastroJan 16, 2025via ghsa
1 file changed · +59 0
  • modules/test/playwright/tests/login-web/createAccount.spec.ts+59 0 added
    @@ -0,0 +1,59 @@
    +/**
    + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com
    + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
    + */
    +
    +import {expect, mergeTests} from '@playwright/test';
    +
    +import {captchaConfigPageTest} from '../../fixtures/captchaConfigPageTest';
    +import {loginTest} from '../../fixtures/loginTest';
    +import {liferayConfig} from '../../liferay.config';
    +import getRandomString from '../../utils/getRandomString';
    +import {performLogout} from '../../utils/performLogin';
    +
    +export const test = mergeTests(loginTest(), captchaConfigPageTest);
    +
    +test.describe('Duplicate account creation', () => {
    +	test('Using already existing email address does not throw failure alert', async ({
    +		captchaConfigPage,
    +		page,
    +	}) => {
    +		await captchaConfigPage.goTo();
    +
    +		await captchaConfigPage.disableCreateAccountCaptcha();
    +
    +		await captchaConfigPage.saveConfiguration();
    +
    +		await performLogout(page);
    +
    +		await page.goto(liferayConfig.environment.baseUrl);
    +
    +		await page.getByRole('button', {name: 'Sign In'}).click();
    +
    +		await page.getByText('Create Account').click();
    +
    +		await page.getByLabel('Screen Name').fill(getRandomString());
    +
    +		await page.getByLabel('Email Address').fill('test@liferay.com');
    +
    +		await page.getByLabel('First Name').fill(getRandomString());
    +
    +		await page.getByLabel('Last Name').fill(getRandomString());
    +
    +		const password = getRandomString();
    +
    +		await page
    +			.getByLabel('Password Required', {exact: true})
    +			.fill(password);
    +
    +		await page.getByLabel('Reenter Password Required').fill(password);
    +
    +		await page.getByRole('button', {name: 'Save'}).click();
    +
    +		await page.waitForTimeout(1000);
    +
    +		await expect(
    +			page.getByText('Error:Your request failed to complete.')
    +		).toBeHidden({timeout: 500});
    +	});
    +});
    
609104647a5a

LPD-44960 Add new methods to captcha page

https://github.com/liferay/liferay-portalManuele CastroJan 16, 2025via ghsa
2 files changed · +76 27
  • modules/test/playwright/pages/captcha-web/CaptchaConfigPage.ts+64 20 modified
    @@ -1,25 +1,25 @@
     /**
    - * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
    + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com
      * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
      */
     
    -import {Locator, Page} from '@playwright/test';
    +import {Locator, Page, expect} from '@playwright/test';
     
     import {waitForAlert} from '../../utils/waitForAlert';
     import {ApplicationsMenuPage} from '../product-navigation-applications-menu/ApplicationsMenuPage';
     
     export class CaptchaConfigPage {
     	readonly applicationsMenuPage: ApplicationsMenuPage;
    +	readonly captchaEngine: Locator;
     	readonly createAccountCaptchaEnabled: Locator;
     	readonly maxChallenges: Locator;
     	readonly messageBoardsEditCategoryCaptchaEnabled: Locator;
     	readonly messageBoardsEditMessageCaptchaEnabled: Locator;
    -	readonly captchaEngine: Locator;
     	readonly page: Page;
    -	readonly reCaptchaPublicKey: Locator;
    +	readonly reCaptchaNoScriptURL: Locator;
     	readonly reCaptchaPrivateKey: Locator;
    +	readonly reCaptchaPublicKey: Locator;
     	readonly reCaptchaScriptURL: Locator;
    -	readonly reCaptchaNoScriptURL: Locator;
     	readonly reCaptchaVerifyURL: Locator;
     	readonly saveButton: Locator;
     	readonly sendPasswordCaptchaEnabled: Locator;
    @@ -29,6 +29,7 @@ export class CaptchaConfigPage {
     
     	constructor(page: Page) {
     		this.applicationsMenuPage = new ApplicationsMenuPage(page);
    +		this.captchaEngine = page.getByLabel('CAPTCHA Engine');
     		this.createAccountCaptchaEnabled = page.getByText(
     			'Create Account CAPTCHA Enabled'
     		);
    @@ -39,14 +40,13 @@ export class CaptchaConfigPage {
     		this.messageBoardsEditMessageCaptchaEnabled = page.getByLabel(
     			'Message Boards Edit Message'
     		);
    -		this.captchaEngine = page.getByLabel('CAPTCHA Engine');
     		this.page = page;
    -		this.reCaptchaPublicKey = page.getByLabel('reCAPTCHA Public Key');
    +		this.reCaptchaNoScriptURL = page.getByLabel('reCAPTCHA No Script URL');
     		this.reCaptchaPrivateKey = page.getByLabel('reCAPTCHA Private Key');
    +		this.reCaptchaPublicKey = page.getByLabel('reCAPTCHA Public Key');
     		this.reCaptchaScriptURL = page.getByLabel('reCAPTCHA Script URL');
    -		this.reCaptchaNoScriptURL = page.getByLabel('reCAPTCHA No Script URL');
    -		this.saveButton = page.getByRole('button', {name: 'Save'});
     		this.reCaptchaVerifyURL = page.getByLabel('reCAPTCHA Verify URL');
    +		this.saveButton = page.getByRole('button', {name: 'Save'});
     		this.sendPasswordCaptchaEnabled = page.getByText(
     			'Send Password CAPTCHA Enabled'
     		);
    @@ -55,32 +55,76 @@ export class CaptchaConfigPage {
     		this.updateButton = page.getByRole('button', {name: 'Update'});
     	}
     
    -	async goTo() {
    -		await this.applicationsMenuPage.goToSystemSettings();
    -		await this.page.getByRole('link', {name: 'Security Tools'}).click();
    +	async disableCaptcha() {
    +		await this.goTo();
     
    -		await this.sendPasswordCaptchaEnabled.waitFor();
    +		await this.maxChallenges.fill('-1');
    +
    +		await this.disableCreateAccountCaptcha();
    +
    +		await this.disableSendPasswordCaptcha();
    +
    +		await this.disableMessageBoardsEditCategoryCaptcha();
    +
    +		await this.disableMessageBoardsEditMessageCaptcha();
    +
    +		await this.saveConfiguration();
    +	}
    +
    +	async disableCreateAccountCaptcha() {
    +		await this.createAccountCaptchaEnabled.uncheck();
    +		await expect(this.createAccountCaptchaEnabled).not.toBeChecked();
    +	}
    +
    +	async disableMessageBoardsEditCategoryCaptcha() {
    +		await this.messageBoardsEditCategoryCaptchaEnabled.uncheck();
    +		await expect(
    +			this.messageBoardsEditCategoryCaptchaEnabled
    +		).not.toBeChecked();
    +	}
    +
    +	async disableMessageBoardsEditMessageCaptcha() {
    +		await this.messageBoardsEditMessageCaptchaEnabled.uncheck();
    +		await expect(
    +			this.messageBoardsEditMessageCaptchaEnabled
    +		).not.toBeChecked();
    +	}
    +
    +	async disableSendPasswordCaptcha() {
    +		await this.sendPasswordCaptchaEnabled.uncheck();
    +		await expect(this.sendPasswordCaptchaEnabled).not.toBeChecked();
     	}
     
     	async enableReCaptcha(publicKey: string, privateKey: string) {
     		await this.captchaEngine.click();
    +
     		await this.page.getByRole('option', {name: 'reCAPTCHA'}).click();
    +
     		await this.reCaptchaPublicKey.fill(publicKey);
    +
     		await this.reCaptchaPrivateKey.fill(privateKey);
    -		this.saveConfiguration();
    -		await waitForAlert(
    -			this.page,
    -			`Success:Your request completed successfully.`
    -		);
    +	}
    +
    +	async goTo() {
    +		await this.applicationsMenuPage.goToSystemSettings();
    +
    +		await this.page.getByRole('link', {name: 'Security Tools'}).click();
    +
    +		await this.sendPasswordCaptchaEnabled.waitFor();
     	}
     
     	async saveConfiguration() {
     		if (await this.page.isVisible('button:has-text("Update")')) {
    -			this.updateButton.click();
    +			await this.updateButton.click();
     
     			return;
     		}
     
    -		this.saveButton.click();
    +		await this.saveButton.click();
    +
    +		await waitForAlert(
    +			this.page,
    +			`Success:Your request completed successfully.`
    +		);
     	}
     }
    
  • modules/test/playwright/tests/captcha-web/recaptcha.spec.ts+12 7 modified
    @@ -1,23 +1,28 @@
     /**
    - * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
    + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com
      * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
      */
     
    -import {expect, test} from '@playwright/test';
    +import {expect, mergeTests} from '@playwright/test';
     
    +import {captchaConfigPageTest} from '../../fixtures/captchaConfigPageTest';
    +import {loginTest} from '../../fixtures/loginTest';
     import {liferayConfig} from '../../liferay.config';
    -import {CaptchaConfigPage} from '../../pages/captcha-web/CaptchaConfigPage';
    -import performLogin, {performLogout} from '../../utils/performLogin';
    +import {performLogout} from '../../utils/performLogin';
     import {reCaptchaConfig} from './config';
     
    -test('LPD-32888 Check reCaptcha has a label for textarea', async ({page}) => {
    -	await performLogin(page, 'test');
    -	const captchaConfigPage = new CaptchaConfigPage(page);
    +export const test = mergeTests(loginTest(), captchaConfigPageTest);
    +
    +test('LPD-32888 Check reCaptcha has a label for textarea', async ({
    +	captchaConfigPage,
    +	page,
    +}) => {
     	await captchaConfigPage.goTo();
     	await captchaConfigPage.enableReCaptcha(
     		reCaptchaConfig.publicKey,
     		reCaptchaConfig.privateKey
     	);
    +	await captchaConfigPage.saveConfiguration();
     
     	await performLogout(page);
     	await page.goto(liferayConfig.environment.baseUrl);
    
7b8376791cfe

LPD-44960 Add captcha page fixture

https://github.com/liferay/liferay-portalManuele CastroJan 16, 2025via ghsa
1 file changed · +18 0
  • modules/test/playwright/fixtures/captchaConfigPageTest.ts+18 0 added
    @@ -0,0 +1,18 @@
    +/**
    + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com
    + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
    + */
    +
    +import {test} from '@playwright/test';
    +
    +import {CaptchaConfigPage} from '../pages/captcha-web/CaptchaConfigPage';
    +
    +const captchaConfigPageTest = test.extend<{
    +	captchaConfigPage: CaptchaConfigPage;
    +}>({
    +	captchaConfigPage: async ({page}, use) => {
    +		await use(new CaptchaConfigPage(page));
    +	},
    +});
    +
    +export {captchaConfigPageTest};
    

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

12

News mentions

0

No linked articles in our index yet.