Skip to content

Commit 9be57d3

Browse files
izaerabrianchandotcom
authored andcommitted
LPS-200229 Resolve path traversals in Combo Servlet
1 parent 2231cd3 commit 9be57d3

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

portal-impl/src/com/liferay/portal/servlet/ComboServlet.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@
4545
import java.io.IOException;
4646
import java.io.Serializable;
4747

48+
import java.util.ArrayList;
4849
import java.util.Arrays;
4950
import java.util.Collections;
5051
import java.util.Enumeration;
5152
import java.util.LinkedHashSet;
53+
import java.util.List;
5254
import java.util.Map;
5355
import java.util.Set;
5456
import java.util.regex.Matcher;
@@ -164,6 +166,12 @@ protected void doService(
164166
name = modulePortletId.concat(name);
165167
}
166168

169+
name = _canonicalizePath(name);
170+
171+
if (Validator.isNull(name)) {
172+
continue;
173+
}
174+
167175
modulePathsSet.add(name);
168176
}
169177

@@ -578,6 +586,36 @@ protected boolean validateModuleExtension(String moduleName)
578586
return validModuleExtension;
579587
}
580588

589+
private String _canonicalizePath(String path) {
590+
if (!path.contains(StringPool.PERIOD)) {
591+
return path;
592+
}
593+
594+
List<String> canonicalParts = new ArrayList<>();
595+
596+
String[] parts = StringUtil.split(path, StringPool.SLASH);
597+
598+
for (String part : parts) {
599+
if (part.equals(StringPool.PERIOD)) {
600+
continue;
601+
}
602+
603+
if (part.equals(StringPool.DOUBLE_PERIOD)) {
604+
if (canonicalParts.isEmpty()) {
605+
return null;
606+
}
607+
608+
canonicalParts.remove(canonicalParts.size() - 1);
609+
610+
continue;
611+
}
612+
613+
canonicalParts.add(part);
614+
}
615+
616+
return StringUtil.merge(canonicalParts, StringPool.SLASH);
617+
}
618+
581619
private String _getModulePathExtension(String modulePath) {
582620
String resourcePath = getResourcePath(modulePath);
583621

portal-impl/test/unit/com/liferay/portal/servlet/ComboServletTest.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ public void testMixedExtensionsRequest() throws Exception {
209209
mockHttpServletResponse.getStatus());
210210
}
211211

212+
@Test
213+
public void testServiceWithNoncanonicalPaths() throws Exception {
214+
_testService(null, "/../js/aui.js", _portalServletContext);
215+
216+
_testService("/js/aui.js", "/./js/aui.js", _portalServletContext);
217+
218+
_testService("/js/aui.js", "/js/./aui.js", _portalServletContext);
219+
220+
_testService("/js/aui.js", "/js/down/../aui.js", _portalServletContext);
221+
}
222+
212223
@Test
213224
public void testServiceWithoutPortletIdButWithContext() throws Exception {
214225
_testService(
@@ -391,7 +402,7 @@ private void _testService(
391402
mockHttpServletRequest, new MockHttpServletResponse());
392403

393404
Mockito.verify(
394-
servletContext
405+
servletContext, Mockito.times((path == null) ? 0 : 1)
395406
).getRequestDispatcher(
396407
path
397408
);

0 commit comments

Comments
 (0)