CVE-2025-62241
Description
Insecure Direct Object Reference (IDOR) vulnerability with shipment addresses in Liferay DXP 2023.Q4.1 through 2023.Q4.5 allows remote authenticated users to from one virtual instance to view the shipment addresses of different virtual instance via the _com_liferay_commerce_order_web_internal_portlet_CommerceOrderPortlet_commerceOrderId parameter.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Liferay DXP 2023.Q4.1-2023.Q4.5 suffers from an IDOR vulnerability allowing authenticated users to view shipment addresses from other virtual instances.
Vulnerability
Description CVE-2025-62241 is an Insecure Direct Object Reference (IDOR) vulnerability in Liferay DXP 2023.Q4.1 through 2023.Q4.5. The issue lies in the Commerce Order portlet, where the _com_liferay_commerce_order_web_internal_portlet_CommerceOrderPortlet_commerceOrderId parameter is not properly validated, allowing a remote authenticated user to access shipment addresses belonging to orders in different virtual instances [1].
Exploitation
An attacker who is authenticated to one virtual instance can manipulate the commerceOrderId parameter to reference an order in another instance. The application fails to verify that the requested order belongs to the same virtual instance as the user, enabling unauthorized access to shipment addresses. No special privileges beyond authentication are required, and the attack can be performed remotely over the network [1].
Impact
Successful exploitation allows the attacker to view shipment addresses of other virtual instances, potentially exposing sensitive customer information such as physical addresses. This violates tenant isolation in multi-tenant deployments and can lead to privacy breaches or further targeted attacks [1][2].
Mitigation
Liferay has addressed the vulnerability by introducing proper permission checks in the CommerceOrderModelResourcePermissionLogic class [2] and by switching from local to remote service calls to enforce cross-instance boundaries [3]. Users should update to a patched version (2023.Q4.6 or later) as recommended by the vendor [1].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.liferay.commerce:com.liferay.commerce.order.content.webMaven | < 4.0.114 | 4.0.114 |
Affected products
2- Liferay/DXPv5Range: 2023.Q4.0
Patches
253401963f02fLPD-16000 Make sure to check supplier order
2 files changed · +34 −12
modules/apps/commerce/commerce-service/src/main/java/com/liferay/commerce/internal/security/permission/resource/CommerceOrderModelResourcePermissionLogic.java+31 −10 modified@@ -14,6 +14,7 @@ import com.liferay.commerce.model.CommerceOrder; import com.liferay.commerce.product.model.CommerceChannel; import com.liferay.commerce.product.service.CommerceChannelLocalService; +import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.petra.string.StringPool; import com.liferay.portal.configuration.module.configuration.ConfigurationProvider; import com.liferay.portal.kernel.dao.orm.QueryUtil; @@ -41,6 +42,7 @@ public class CommerceOrderModelResourcePermissionLogic public CommerceOrderModelResourcePermissionLogic( AccountEntryLocalService accountEntryLocalService, CommerceChannelLocalService commerceChannelLocalService, + CommerceOrderLocalService commerceOrderLocalService, ConfigurationProvider configurationProvider, GroupLocalService groupLocalService, PortletResourcePermission portletResourcePermission, @@ -49,6 +51,7 @@ public CommerceOrderModelResourcePermissionLogic( _accountEntryLocalService = accountEntryLocalService; _commerceChannelLocalService = commerceChannelLocalService; + _commerceOrderLocalService = commerceOrderLocalService; _configurationProvider = configurationProvider; _groupLocalService = groupLocalService; _portletResourcePermission = portletResourcePermission; @@ -476,23 +479,17 @@ private boolean _hasRoleAccountSupplier( PermissionChecker permissionChecker, CommerceOrder commerceOrder) throws PortalException { - CommerceChannel commerceChannel = - _commerceChannelLocalService.fetchCommerceChannelByGroupClassPK( - commerceOrder.getGroupId()); - - if ((commerceChannel != null) && - (commerceChannel.getAccountEntryId() == 0)) { - - return false; - } - List<AccountEntry> accountEntries = _accountEntryLocalService.getUserAccountEntries( permissionChecker.getUserId(), 0L, StringPool.BLANK, new String[] {AccountConstants.ACCOUNT_ENTRY_TYPE_SUPPLIER}, QueryUtil.ALL_POS, QueryUtil.ALL_POS); for (AccountEntry accountEntry : accountEntries) { + CommerceChannel commerceChannel = + _commerceChannelLocalService.fetchCommerceChannelByGroupClassPK( + commerceOrder.getGroupId()); + if ((accountEntry.getAccountEntryId() == commerceChannel.getAccountEntryId()) && _userGroupRoleLocalService.hasUserGroupRole( @@ -502,13 +499,37 @@ private boolean _hasRoleAccountSupplier( return true; } + + for (long commerceOrderIds : + commerceOrder.getSupplierCommerceOrderIds()) { + + CommerceOrder supplierCommerceOrder = + _commerceOrderLocalService.getCommerceOrder( + commerceOrderIds); + + commerceChannel = + _commerceChannelLocalService. + fetchCommerceChannelByGroupClassPK( + supplierCommerceOrder.getGroupId()); + + if ((accountEntry.getAccountEntryId() == + commerceChannel.getAccountEntryId()) && + _userGroupRoleLocalService.hasUserGroupRole( + permissionChecker.getUserId(), + accountEntry.getAccountEntryGroupId(), + AccountRoleConstants.ROLE_NAME_ACCOUNT_SUPPLIER)) { + + return true; + } + } } return false; } private final AccountEntryLocalService _accountEntryLocalService; private final CommerceChannelLocalService _commerceChannelLocalService; + private final CommerceOrderLocalService _commerceOrderLocalService; private final ConfigurationProvider _configurationProvider; private final GroupLocalService _groupLocalService; private final PortletResourcePermission _portletResourcePermission;
modules/apps/commerce/commerce-service/src/main/java/com/liferay/commerce/internal/security/permission/resource/CommerceOrderModelResourcePermissionWrapper.java+3 −2 modified@@ -49,8 +49,9 @@ public class CommerceOrderModelResourcePermissionWrapper consumer.accept( new CommerceOrderModelResourcePermissionLogic( _accountEntryLocalService, _commerceChannelLocalService, - _configurationProvider, _groupLocalService, - _portletResourcePermission, _userGroupRoleLocalService, + _commerceOrderLocalService, _configurationProvider, + _groupLocalService, _portletResourcePermission, + _userGroupRoleLocalService, _workflowDefinitionLinkLocalService)); }); }
75c39ea518ebLPD-16000 Use non local service so that permission is checked for virtual instances
9 files changed · +30 −30
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/display/context/CommerceShipmentDisplayContext.java+6 −6 modified@@ -22,7 +22,7 @@ import com.liferay.commerce.model.CommerceShippingMethod; import com.liferay.commerce.product.model.CommerceChannel; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -76,7 +76,7 @@ public class CommerceShipmentDisplayContext public CommerceShipmentDisplayContext( ActionHelper actionHelper, CommerceAddressFormatter commerceAddressFormatter, - CommerceAddressLocalService commerceAddressLocalService, + CommerceAddressService commerceAddressService, CommerceChannelService commerceChannelService, CommerceOrderItemService commerceOrderItemService, CommerceOrderLocalService commerceOrderLocalService, @@ -89,7 +89,7 @@ public CommerceShipmentDisplayContext( super(actionHelper, httpServletRequest, portletResourcePermission); _commerceAddressFormatter = commerceAddressFormatter; - _commerceAddressLocalService = commerceAddressLocalService; + _commerceAddressService = commerceAddressService; _commerceChannelService = commerceChannelService; _commerceOrderItemService = commerceOrderItemService; _commerceOrderLocalService = commerceOrderLocalService; @@ -186,7 +186,7 @@ public List<CommerceShippingMethod> getCommerceShippingMethods() } CommerceAddress commerceAddress = - _commerceAddressLocalService.getCommerceAddress( + _commerceAddressService.getCommerceAddress( commerceShipment.getCommerceAddressId()); return _commerceShippingMethodService.getCommerceShippingMethods( @@ -413,7 +413,7 @@ else if ((commerceShipment.getStatus() > shipmentStatus) || public CommerceAddress getShippingAddress() throws PortalException { CommerceShipment commerceShipment = getCommerceShipment(); - return _commerceAddressLocalService.fetchCommerceAddress( + return _commerceAddressService.fetchCommerceAddress( commerceShipment.getCommerceAddressId()); } @@ -488,7 +488,7 @@ private SearchContext _buildSearchContext() throws PortalException { CommerceShipmentDisplayContext.class); private final CommerceAddressFormatter _commerceAddressFormatter; - private final CommerceAddressLocalService _commerceAddressLocalService; + private final CommerceAddressService _commerceAddressService; private final CommerceChannelService _commerceChannelService; private final CommerceOrderItemService _commerceOrderItemService; private final CommerceOrderLocalService _commerceOrderLocalService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/action/AddCommerceShipmentItemsMVCRenderCommand.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -51,7 +51,7 @@ public String render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -70,7 +70,7 @@ public String render( private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/action/AddCommerceShipmentMVCRenderCommand.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -50,7 +50,7 @@ public String render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -69,7 +69,7 @@ public String render( private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/action/EditCommerceShipmentAddressMVCRenderCommand.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -51,7 +51,7 @@ public String render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -70,7 +70,7 @@ public String render( private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/action/EditCommerceShipmentCourierDetailMVCRenderCommand.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -51,7 +51,7 @@ public String render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -70,7 +70,7 @@ public String render( private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/action/EditCommerceShipmentExpectedDateMVCRenderCommand.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -51,7 +51,7 @@ public String render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -70,7 +70,7 @@ public String render( private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/action/EditCommerceShipmentMVCRenderCommand.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -55,7 +55,7 @@ public String render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -111,7 +111,7 @@ private void _populatePortletDisplay(RenderRequest renderRequest) { private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/action/EditCommerceShipmentShippingDateMVCRenderCommand.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -51,7 +51,7 @@ public String render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -70,7 +70,7 @@ public String render( private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
modules/apps/commerce/commerce-shipment-web/src/main/java/com/liferay/commerce/shipment/web/internal/portlet/CommerceShipmentPortlet.java+3 −3 modified@@ -9,7 +9,7 @@ import com.liferay.commerce.constants.CommerceConstants; import com.liferay.commerce.constants.CommercePortletKeys; import com.liferay.commerce.product.service.CommerceChannelService; -import com.liferay.commerce.service.CommerceAddressLocalService; +import com.liferay.commerce.service.CommerceAddressService; import com.liferay.commerce.service.CommerceOrderItemService; import com.liferay.commerce.service.CommerceOrderLocalService; import com.liferay.commerce.service.CommerceShipmentItemService; @@ -68,7 +68,7 @@ public void render( CommerceShipmentDisplayContext commerceShipmentDisplayContext = new CommerceShipmentDisplayContext( _actionHelper, _commerceAddressFormatter, - _commerceAddressLocalService, _commerceChannelService, + _commerceAddressService, _commerceChannelService, _commerceOrderItemService, _commerceOrderLocalService, _commerceShipmentItemService, _commerceShippingMethodService, _countryService, _portal.getHttpServletRequest(renderRequest), @@ -87,7 +87,7 @@ public void render( private CommerceAddressFormatter _commerceAddressFormatter; @Reference - private CommerceAddressLocalService _commerceAddressLocalService; + private CommerceAddressService _commerceAddressService; @Reference private CommerceChannelService _commerceChannelService;
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-fhcw-px4q-pmvvghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-62241ghsaADVISORY
- github.com/liferay/liferay-portal/commit/53401963f02f593bbf555b4b321fdaeb59e03a53ghsaWEB
- github.com/liferay/liferay-portal/commit/75c39ea518eb91b3b5cbb0576074ebbbfd805401ghsaWEB
- liferay.atlassian.net/browse/LPE-17936ghsaWEB
- liferay.dev/portal/security/known-vulnerabilities/-/asset_publisher/jekt/content/CVE-2025-62241ghsaWEB
News mentions
0No linked articles in our index yet.