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

CVE-2025-43757

CVE-2025-43757

Description

A reflected cross-site scripting (XSS) vulnerability in the Liferay Portal 7.4.0 through 7.4.3.132, and Liferay DXP 2025.Q2.0 through 2025.Q2.2, 2025.Q1.0 through 2025.Q1.14, 2024.Q4.0 through 2024.Q4.7, 2024.Q3.1 through 2024.Q3.13, 2024.Q2.1 through 2024.Q2.13, 2024.Q1.1 through 2024.Q1.18 and 7.4 GA through update 92 allows a remote authenticated attacker to inject JavaScript code via _com_liferay_dynamic_data_mapping_web_portlet_DDMPortlet_definition parameter.

Affected packages

Versions sourced from the GitHub Security Advisory.

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

Affected products

2

Patches

8
cc46176ba414

Revert "LPD-56406 Escape Parameter URL in RenderStructureFieldMVCResourceCommand"

1 file changed · +2 2
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web/src/main/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommand.java+2 2 modified
    @@ -124,8 +124,8 @@ protected void doServeResource(
     	protected DDMFormField getDDMFormField(
     		HttpServletRequest httpServletRequest) {
     
    -		String definition = HtmlUtil.escapeAttribute(
    -			ParamUtil.getString(httpServletRequest, "definition"));
    +		String definition = ParamUtil.getString(
    +			httpServletRequest, "definition");
     		String fieldName = ParamUtil.getString(httpServletRequest, "fieldName");
     
     		DDMFormDeserializerDeserializeRequest.Builder builder =
    
45492d30bad4

LPD-56406 SF

https://github.com/liferay/liferay-portalBrian ChanJun 16, 2025via ghsa
1 file changed · +6 6
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web-test/src/test/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommandTest.java+6 6 modified
    @@ -99,15 +99,15 @@ public void testGetDDMFormField() {
     			HtmlUtil.escapeAttribute(_SCRIPT)
     		);
     
    -		DDMFormDeserializer jsonDDMFormDeserializer = Mockito.mock(
    +		DDMFormDeserializer ddmFormDeserializer = Mockito.mock(
     			DDMFormDeserializer.class);
     
     		DDMFormDeserializerDeserializeResponse
     			ddmFormDeserializerDeserializeResponse = Mockito.mock(
     				DDMFormDeserializerDeserializeResponse.class);
     
     		Mockito.when(
    -			jsonDDMFormDeserializer.deserialize(Mockito.any())
    +			ddmFormDeserializer.deserialize(Mockito.any())
     		).thenReturn(
     			ddmFormDeserializerDeserializeResponse
     		);
    @@ -120,10 +120,10 @@ public void testGetDDMFormField() {
     			ddmForm
     		);
     
    -		DDMFormField ddmFormFieldMock = Mockito.mock(DDMFormField.class);
    +		DDMFormField mockDDMFormField = Mockito.mock(DDMFormField.class);
     
     		Mockito.when(
    -			ddmFormFieldMock.getName()
    +			mockDDMFormField.getName()
     		).thenReturn(
     			HtmlUtil.escapeAttribute(_SCRIPT)
     		);
    @@ -132,7 +132,7 @@ public void testGetDDMFormField() {
     			ddmForm.getDDMFormFieldsMap(true)
     		).thenReturn(
     			Collections.singletonMap(
    -				HtmlUtil.escapeAttribute(_SCRIPT), ddmFormFieldMock)
    +				HtmlUtil.escapeAttribute(_SCRIPT), mockDDMFormField)
     		);
     
     		RenderStructureFieldMVCResourceCommand
    @@ -141,7 +141,7 @@ public void testGetDDMFormField() {
     
     		ReflectionTestUtil.setFieldValue(
     			renderStructureFieldMVCResourceCommand, "_jsonDDMFormDeserializer",
    -			jsonDDMFormDeserializer);
    +			ddmFormDeserializer);
     
     		DDMFormField ddmFormField =
     			renderStructureFieldMVCResourceCommand.getDDMFormField(
    
90396a201d05

LPD-56406 SF

https://github.com/liferay/liferay-portalMarcela CunhaJun 13, 2025via ghsa
1 file changed · +17 17
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web-test/src/test/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommandTest.java+17 17 modified
    @@ -99,40 +99,40 @@ public void testGetDDMFormField() {
     			HtmlUtil.escapeAttribute(_SCRIPT)
     		);
     
    -		DDMFormField ddmFormFieldMock = Mockito.mock(DDMFormField.class);
    +		DDMFormDeserializer jsonDDMFormDeserializer = Mockito.mock(
    +			DDMFormDeserializer.class);
    +
    +		DDMFormDeserializerDeserializeResponse
    +			ddmFormDeserializerDeserializeResponse = Mockito.mock(
    +				DDMFormDeserializerDeserializeResponse.class);
     
     		Mockito.when(
    -			ddmFormFieldMock.getName()
    +			jsonDDMFormDeserializer.deserialize(Mockito.any())
     		).thenReturn(
    -			HtmlUtil.escapeAttribute(_SCRIPT)
    +			ddmFormDeserializerDeserializeResponse
     		);
     
     		DDMForm ddmForm = Mockito.mock(DDMForm.class);
     
     		Mockito.when(
    -			ddmForm.getDDMFormFieldsMap(true)
    +			ddmFormDeserializerDeserializeResponse.getDDMForm()
     		).thenReturn(
    -			Collections.singletonMap(
    -				HtmlUtil.escapeAttribute(_SCRIPT), ddmFormFieldMock)
    +			ddmForm
     		);
     
    -		DDMFormDeserializerDeserializeResponse
    -			ddmFormDeserializerDeserializeResponseMock = Mockito.mock(
    -				DDMFormDeserializerDeserializeResponse.class);
    +		DDMFormField ddmFormFieldMock = Mockito.mock(DDMFormField.class);
     
     		Mockito.when(
    -			ddmFormDeserializerDeserializeResponseMock.getDDMForm()
    +			ddmFormFieldMock.getName()
     		).thenReturn(
    -			ddmForm
    +			HtmlUtil.escapeAttribute(_SCRIPT)
     		);
     
    -		DDMFormDeserializer jsonDDMFormDeserializerMock = Mockito.mock(
    -			DDMFormDeserializer.class);
    -
     		Mockito.when(
    -			jsonDDMFormDeserializerMock.deserialize(Mockito.any())
    +			ddmForm.getDDMFormFieldsMap(true)
     		).thenReturn(
    -			ddmFormDeserializerDeserializeResponseMock
    +			Collections.singletonMap(
    +				HtmlUtil.escapeAttribute(_SCRIPT), ddmFormFieldMock)
     		);
     
     		RenderStructureFieldMVCResourceCommand
    @@ -141,7 +141,7 @@ public void testGetDDMFormField() {
     
     		ReflectionTestUtil.setFieldValue(
     			renderStructureFieldMVCResourceCommand, "_jsonDDMFormDeserializer",
    -			jsonDDMFormDeserializerMock);
    +			jsonDDMFormDeserializer);
     
     		DDMFormField ddmFormField =
     			renderStructureFieldMVCResourceCommand.getDDMFormField(
    
d001c5ba8a14

LPD-56406 Not necessary for this test

https://github.com/liferay/liferay-portalMarcela CunhaJun 13, 2025via ghsa
1 file changed · +0 9
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web-test/src/test/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommandTest.java+0 9 modified
    @@ -93,12 +93,6 @@ public void testCreateDDMFormFieldRenderingContext() {
     
     	@Test
     	public void testGetDDMFormField() {
    -		Mockito.when(
    -			_httpServletRequest.getParameter("definition")
    -		).thenReturn(
    -			_SCRIPT
    -		);
    -
     		Mockito.when(
     			_httpServletRequest.getParameter("fieldName")
     		).thenReturn(
    @@ -145,9 +139,6 @@ public void testGetDDMFormField() {
     			renderStructureFieldMVCResourceCommand =
     				new RenderStructureFieldMVCResourceCommand();
     
    -		ReflectionTestUtil.setFieldValue(
    -			renderStructureFieldMVCResourceCommand, "_portal", _portal);
    -
     		ReflectionTestUtil.setFieldValue(
     			renderStructureFieldMVCResourceCommand, "_jsonDDMFormDeserializer",
     			jsonDDMFormDeserializerMock);
    
e83d102bf00a

LPD-56406 Make the method protected so you can test it

https://github.com/liferay/liferay-portalMarcela CunhaJun 13, 2025via ghsa
2 files changed · +5 5
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web/src/main/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommand.java+2 2 modified
    @@ -103,7 +103,7 @@ protected void doServeResource(
     		HttpServletRequest httpServletRequest = _portal.getHttpServletRequest(
     			resourceRequest);
     
    -		DDMFormField ddmFormField = _getDDMFormField(httpServletRequest);
    +		DDMFormField ddmFormField = getDDMFormField(httpServletRequest);
     
     		DDMFormFieldRenderer ddmFormFieldRenderer =
     			_ddmFormFieldRendererRegistry.getDDMFormFieldRenderer(
    @@ -121,7 +121,7 @@ protected void doServeResource(
     		ServletResponseUtil.write(httpServletResponse, ddmFormFieldHTML);
     	}
     
    -	private DDMFormField _getDDMFormField(
    +	protected DDMFormField getDDMFormField(
     		HttpServletRequest httpServletRequest) {
     
     		String definition = HtmlUtil.escapeAttribute(
    
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web-test/src/test/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommandTest.java+3 3 modified
    @@ -152,9 +152,9 @@ public void testGetDDMFormField() {
     			renderStructureFieldMVCResourceCommand, "_jsonDDMFormDeserializer",
     			jsonDDMFormDeserializerMock);
     
    -		DDMFormField ddmFormField = ReflectionTestUtil.invoke(
    -			renderStructureFieldMVCResourceCommand, "_getDDMFormField",
    -			new Class<?>[] {HttpServletRequest.class}, _httpServletRequest);
    +		DDMFormField ddmFormField =
    +			renderStructureFieldMVCResourceCommand.getDDMFormField(
    +				_httpServletRequest);
     
     		Assert.assertEquals(
     			HtmlUtil.escapeAttribute(_SCRIPT), ddmFormField.getName());
    
0837982b91c5

LPD-56406 Setup method with common logic

https://github.com/liferay/liferay-portalMarcela CunhaJun 13, 2025via ghsa
1 file changed · +27 42
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web-test/src/test/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommandTest.java+27 42 modified
    @@ -24,6 +24,7 @@
     import java.util.Collections;
     
     import org.junit.Assert;
    +import org.junit.Before;
     import org.junit.ClassRule;
     import org.junit.Test;
     
    @@ -38,11 +39,8 @@ public class RenderStructureFieldMVCResourceCommandTest {
     	public static final LiferayUnitTestRule liferayUnitTestRule =
     		LiferayUnitTestRule.INSTANCE;
     
    -	@Test
    -	public void testCreateDDMFormFieldRenderingContext() {
    -		HttpServletRequest httpServletRequest = Mockito.mock(
    -			HttpServletRequest.class);
    -
    +	@Before
    +	public void setUp() throws Exception {
     		ThemeDisplay themeDisplay = Mockito.mock(ThemeDisplay.class);
     
     		Mockito.when(
    @@ -52,23 +50,24 @@ public void testCreateDDMFormFieldRenderingContext() {
     		);
     
     		Mockito.when(
    -			httpServletRequest.getAttribute(WebKeys.THEME_DISPLAY)
    +			_httpServletRequest.getAttribute(WebKeys.THEME_DISPLAY)
     		).thenReturn(
     			themeDisplay
     		);
    +	}
     
    -		String script = "'\"></option><img onerror=alert(123) src=x>";
    -
    +	@Test
    +	public void testCreateDDMFormFieldRenderingContext() {
     		Mockito.when(
    -			httpServletRequest.getParameter("namespace")
    +			_httpServletRequest.getParameter("namespace")
     		).thenReturn(
    -			script
    +			_SCRIPT
     		);
     
     		Mockito.when(
    -			httpServletRequest.getParameter("portletNamespace")
    +			_httpServletRequest.getParameter("portletNamespace")
     		).thenReturn(
    -			script
    +			_SCRIPT
     		);
     
     		RenderStructureFieldMVCResourceCommand
    @@ -81,56 +80,37 @@ public void testCreateDDMFormFieldRenderingContext() {
     		DDMFormFieldRenderingContext ddmFormFieldRenderingContext =
     			renderStructureFieldMVCResourceCommand.
     				createDDMFormFieldRenderingContext(
    -					httpServletRequest,
    +					_httpServletRequest,
     					Mockito.mock(HttpServletResponse.class));
     
     		Assert.assertEquals(
    -			HtmlUtil.escapeAttribute(script),
    +			HtmlUtil.escapeAttribute(_SCRIPT),
     			ddmFormFieldRenderingContext.getNamespace());
     		Assert.assertEquals(
    -			HtmlUtil.escapeAttribute(script),
    +			HtmlUtil.escapeAttribute(_SCRIPT),
     			ddmFormFieldRenderingContext.getPortletNamespace());
     	}
     
     	@Test
     	public void testGetDDMFormField() {
    -		HttpServletRequest httpServletRequest = Mockito.mock(
    -			HttpServletRequest.class);
    -
    -		ThemeDisplay themeDisplay = Mockito.mock(ThemeDisplay.class);
    -
     		Mockito.when(
    -			themeDisplay.getLocale()
    +			_httpServletRequest.getParameter("definition")
     		).thenReturn(
    -			LocaleUtil.US
    +			_SCRIPT
     		);
     
     		Mockito.when(
    -			httpServletRequest.getAttribute(WebKeys.THEME_DISPLAY)
    +			_httpServletRequest.getParameter("fieldName")
     		).thenReturn(
    -			themeDisplay
    -		);
    -
    -		String script = "'\"></option><img onerror=alert(123) src=x>";
    -
    -		Mockito.when(
    -			httpServletRequest.getParameter("definition")
    -		).thenReturn(
    -			script
    -		);
    -
    -		Mockito.when(
    -			httpServletRequest.getParameter("fieldName")
    -		).thenReturn(
    -			HtmlUtil.escapeAttribute(script)
    +			HtmlUtil.escapeAttribute(_SCRIPT)
     		);
     
     		DDMFormField ddmFormFieldMock = Mockito.mock(DDMFormField.class);
     
     		Mockito.when(
     			ddmFormFieldMock.getName()
     		).thenReturn(
    -			HtmlUtil.escapeAttribute(script)
    +			HtmlUtil.escapeAttribute(_SCRIPT)
     		);
     
     		DDMForm ddmForm = Mockito.mock(DDMForm.class);
    @@ -139,7 +119,7 @@ public void testGetDDMFormField() {
     			ddmForm.getDDMFormFieldsMap(true)
     		).thenReturn(
     			Collections.singletonMap(
    -				HtmlUtil.escapeAttribute(script), ddmFormFieldMock)
    +				HtmlUtil.escapeAttribute(_SCRIPT), ddmFormFieldMock)
     		);
     
     		DDMFormDeserializerDeserializeResponse
    @@ -174,12 +154,17 @@ public void testGetDDMFormField() {
     
     		DDMFormField ddmFormField = ReflectionTestUtil.invoke(
     			renderStructureFieldMVCResourceCommand, "_getDDMFormField",
    -			new Class<?>[] {HttpServletRequest.class}, httpServletRequest);
    +			new Class<?>[] {HttpServletRequest.class}, _httpServletRequest);
     
     		Assert.assertEquals(
    -			HtmlUtil.escapeAttribute(script), ddmFormField.getName());
    +			HtmlUtil.escapeAttribute(_SCRIPT), ddmFormField.getName());
     	}
     
    +	private static final String _SCRIPT =
    +		"'\"></option><img onerror=alert(123) src=x>";
    +
    +	private final HttpServletRequest _httpServletRequest = Mockito.mock(
    +		HttpServletRequest.class);
     	private final Portal _portal = Mockito.mock(Portal.class);
     
     }
    \ No newline at end of file
    
0114bb60238e

LPD-56406 Add test

1 file changed · +94 0
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web-test/src/test/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommandTest.java+94 0 modified
    @@ -5,6 +5,10 @@
     
     package com.liferay.dynamic.data.mapping.web.internal.portlet.action;
     
    +import com.liferay.dynamic.data.mapping.io.DDMFormDeserializer;
    +import com.liferay.dynamic.data.mapping.io.DDMFormDeserializerDeserializeResponse;
    +import com.liferay.dynamic.data.mapping.model.DDMForm;
    +import com.liferay.dynamic.data.mapping.model.DDMFormField;
     import com.liferay.dynamic.data.mapping.render.DDMFormFieldRenderingContext;
     import com.liferay.portal.kernel.test.ReflectionTestUtil;
     import com.liferay.portal.kernel.theme.ThemeDisplay;
    @@ -17,6 +21,8 @@
     import jakarta.servlet.http.HttpServletRequest;
     import jakarta.servlet.http.HttpServletResponse;
     
    +import java.util.Collections;
    +
     import org.junit.Assert;
     import org.junit.ClassRule;
     import org.junit.Test;
    @@ -86,6 +92,94 @@ public void testCreateDDMFormFieldRenderingContext() {
     			ddmFormFieldRenderingContext.getPortletNamespace());
     	}
     
    +	@Test
    +	public void testGetDDMFormField() {
    +		HttpServletRequest httpServletRequest = Mockito.mock(
    +			HttpServletRequest.class);
    +
    +		ThemeDisplay themeDisplay = Mockito.mock(ThemeDisplay.class);
    +
    +		Mockito.when(
    +			themeDisplay.getLocale()
    +		).thenReturn(
    +			LocaleUtil.US
    +		);
    +
    +		Mockito.when(
    +			httpServletRequest.getAttribute(WebKeys.THEME_DISPLAY)
    +		).thenReturn(
    +			themeDisplay
    +		);
    +
    +		String script = "'\"></option><img onerror=alert(123) src=x>";
    +
    +		Mockito.when(
    +			httpServletRequest.getParameter("definition")
    +		).thenReturn(
    +			script
    +		);
    +
    +		Mockito.when(
    +			httpServletRequest.getParameter("fieldName")
    +		).thenReturn(
    +			HtmlUtil.escapeAttribute(script)
    +		);
    +
    +		DDMFormField ddmFormFieldMock = Mockito.mock(DDMFormField.class);
    +
    +		Mockito.when(
    +			ddmFormFieldMock.getName()
    +		).thenReturn(
    +			HtmlUtil.escapeAttribute(script)
    +		);
    +
    +		DDMForm ddmForm = Mockito.mock(DDMForm.class);
    +
    +		Mockito.when(
    +			ddmForm.getDDMFormFieldsMap(true)
    +		).thenReturn(
    +			Collections.singletonMap(
    +				HtmlUtil.escapeAttribute(script), ddmFormFieldMock)
    +		);
    +
    +		DDMFormDeserializerDeserializeResponse
    +			ddmFormDeserializerDeserializeResponseMock = Mockito.mock(
    +				DDMFormDeserializerDeserializeResponse.class);
    +
    +		Mockito.when(
    +			ddmFormDeserializerDeserializeResponseMock.getDDMForm()
    +		).thenReturn(
    +			ddmForm
    +		);
    +
    +		DDMFormDeserializer jsonDDMFormDeserializerMock = Mockito.mock(
    +			DDMFormDeserializer.class);
    +
    +		Mockito.when(
    +			jsonDDMFormDeserializerMock.deserialize(Mockito.any())
    +		).thenReturn(
    +			ddmFormDeserializerDeserializeResponseMock
    +		);
    +
    +		RenderStructureFieldMVCResourceCommand
    +			renderStructureFieldMVCResourceCommand =
    +				new RenderStructureFieldMVCResourceCommand();
    +
    +		ReflectionTestUtil.setFieldValue(
    +			renderStructureFieldMVCResourceCommand, "_portal", _portal);
    +
    +		ReflectionTestUtil.setFieldValue(
    +			renderStructureFieldMVCResourceCommand, "_jsonDDMFormDeserializer",
    +			jsonDDMFormDeserializerMock);
    +
    +		DDMFormField ddmFormField = ReflectionTestUtil.invoke(
    +			renderStructureFieldMVCResourceCommand, "_getDDMFormField",
    +			new Class<?>[] {HttpServletRequest.class}, httpServletRequest);
    +
    +		Assert.assertEquals(
    +			HtmlUtil.escapeAttribute(script), ddmFormField.getName());
    +	}
    +
     	private final Portal _portal = Mockito.mock(Portal.class);
     
     }
    \ No newline at end of file
    
9e0026c8aa44

LPD-56406 Escape Parameter URL in RenderStructureFieldMVCResourceCommand

1 file changed · +2 2
  • modules/apps/dynamic-data-mapping/dynamic-data-mapping-web/src/main/java/com/liferay/dynamic/data/mapping/web/internal/portlet/action/RenderStructureFieldMVCResourceCommand.java+2 2 modified
    @@ -124,8 +124,8 @@ protected void doServeResource(
     	private DDMFormField _getDDMFormField(
     		HttpServletRequest httpServletRequest) {
     
    -		String definition = ParamUtil.getString(
    -			httpServletRequest, "definition");
    +		String definition = HtmlUtil.escapeAttribute(
    +			ParamUtil.getString(httpServletRequest, "definition"));
     		String fieldName = ParamUtil.getString(httpServletRequest, "fieldName");
     
     		DDMFormDeserializerDeserializeRequest.Builder builder =
    

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.