CVE-2025-43813
Description
Possible path traversal vulnerability and denial-of-service in the ComboServlet in Liferay Portal 7.4.0 through 7.4.3.107, and older unsupported versions, and Liferay DXP 2023.Q4.0 through 2023.Q4.4, 2023.Q3.1 through 2023.Q3.8, 7.4 GA through update 92, 7.3 GA through update 35, and older unsupported versions allows remote attackers to access arbitrary CSS and JSS files and load the files multiple times via the query string in a URL.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.liferay.portal:release.portal.bomMaven | >= 7.4.0-ga1, < 7.4.3.108-ga108 | 7.4.3.108-ga108 |
com.liferay.portal:com.liferay.portal.implMaven | < 96.0.0 | 96.0.0 |
Affected products
2- Liferay/DXPv5Range: 7.3.10
Patches
37acad68976e8LPS-200229 Sublime Sort
1 file changed · +1 −5
portal-impl/test/unit/com/liferay/portal/servlet/ComboServletTest.java+1 −5 modified@@ -211,15 +211,11 @@ public void testMixedExtensionsRequest() throws Exception { @Test public void testServiceWithNoncanonicalPaths() throws Exception { - _testService(null, "/../js/aui.js", _portalServletContext); - _testService("/js/aui.js", "/./js/aui.js", _portalServletContext); - _testService("/js/aui.js", "/js/./aui.js", _portalServletContext); - _testService("/js/aui.js", "/js//aui.js", _portalServletContext); - _testService("/js/aui.js", "/js/down/../aui.js", _portalServletContext); + _testService(null, "/../js/aui.js", _portalServletContext); } @Test
9159075ede8aLPS-200229 Ignore multiple / inside paths in Combo Servlet
2 files changed · +8 −2
portal-impl/src/com/liferay/portal/servlet/ComboServlet.java+6 −2 modified@@ -595,8 +595,12 @@ private String _canonicalizePath(String path) { String[] parts = StringUtil.split(path, StringPool.SLASH); - for (String part : parts) { - if (part.equals(StringPool.PERIOD)) { + for (int i = 0; i < parts.length; i++) { + String part = parts[i]; + + if (((i != 0) && Validator.isBlank(part)) || + part.equals(StringPool.PERIOD)) { + continue; }
portal-impl/test/unit/com/liferay/portal/servlet/ComboServletTest.java+2 −0 modified@@ -217,6 +217,8 @@ public void testServiceWithNoncanonicalPaths() throws Exception { _testService("/js/aui.js", "/js/./aui.js", _portalServletContext); + _testService("/js/aui.js", "/js//aui.js", _portalServletContext); + _testService("/js/aui.js", "/js/down/../aui.js", _portalServletContext); }
9be57d358ae0LPS-200229 Resolve path traversals in Combo Servlet
2 files changed · +50 −1
portal-impl/src/com/liferay/portal/servlet/ComboServlet.java+38 −0 modified@@ -45,10 +45,12 @@ import java.io.IOException; import java.io.Serializable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; @@ -164,6 +166,12 @@ protected void doService( name = modulePortletId.concat(name); } + name = _canonicalizePath(name); + + if (Validator.isNull(name)) { + continue; + } + modulePathsSet.add(name); } @@ -578,6 +586,36 @@ protected boolean validateModuleExtension(String moduleName) return validModuleExtension; } + private String _canonicalizePath(String path) { + if (!path.contains(StringPool.PERIOD)) { + return path; + } + + List<String> canonicalParts = new ArrayList<>(); + + String[] parts = StringUtil.split(path, StringPool.SLASH); + + for (String part : parts) { + if (part.equals(StringPool.PERIOD)) { + continue; + } + + if (part.equals(StringPool.DOUBLE_PERIOD)) { + if (canonicalParts.isEmpty()) { + return null; + } + + canonicalParts.remove(canonicalParts.size() - 1); + + continue; + } + + canonicalParts.add(part); + } + + return StringUtil.merge(canonicalParts, StringPool.SLASH); + } + private String _getModulePathExtension(String modulePath) { String resourcePath = getResourcePath(modulePath);
portal-impl/test/unit/com/liferay/portal/servlet/ComboServletTest.java+12 −1 modified@@ -209,6 +209,17 @@ public void testMixedExtensionsRequest() throws Exception { mockHttpServletResponse.getStatus()); } + @Test + public void testServiceWithNoncanonicalPaths() throws Exception { + _testService(null, "/../js/aui.js", _portalServletContext); + + _testService("/js/aui.js", "/./js/aui.js", _portalServletContext); + + _testService("/js/aui.js", "/js/./aui.js", _portalServletContext); + + _testService("/js/aui.js", "/js/down/../aui.js", _portalServletContext); + } + @Test public void testServiceWithoutPortletIdButWithContext() throws Exception { _testService( @@ -391,7 +402,7 @@ private void _testService( mockHttpServletRequest, new MockHttpServletResponse()); Mockito.verify( - servletContext + servletContext, Mockito.times((path == null) ? 0 : 1) ).getRequestDispatcher( path );
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
7- github.com/advisories/GHSA-2hm7-r8f3-423hghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-43813ghsaADVISORY
- github.com/liferay/liferay-portal/commit/7acad68976e831a0f3b855752ad7874e03be1d43ghsaWEB
- github.com/liferay/liferay-portal/commit/9159075ede8a1656bf67a893a486c93a9e9fe70aghsaWEB
- github.com/liferay/liferay-portal/commit/9be57d358ae0f6181a138ce08f52b80e4b14778aghsaWEB
- liferay.atlassian.net/browse/LPE-17865ghsaWEB
- liferay.dev/portal/security/known-vulnerabilities/-/asset_publisher/jekt/content/CVE-2025-43813ghsaWEB
News mentions
0No linked articles in our index yet.