Skip to content

Commit c7f76bd

Browse files
authored
[GWC-1210] Improve input validation in ByteStreamController (#1211)
1 parent 9b55d9a commit c7f76bd

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

geowebcache/rest/src/main/java/org/geowebcache/rest/controller/ByteStreamController.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616
package org.geowebcache.rest.controller;
1717

18+
import java.io.File;
1819
import java.io.IOException;
1920
import java.io.InputStream;
20-
import java.io.UnsupportedEncodingException;
2121
import java.net.URL;
2222
import java.net.URLDecoder;
2323
import java.util.List;
@@ -79,22 +79,21 @@ protected URL getResource(String path) {
7979

8080
// "gwc/rest/web/openlayers3/ol.js" -> openlayers3/ol.js
8181
// "/rest/web/openlayers3/ol.js" -> openlayers3/ol.js
82-
String getFileName(HttpServletRequest request) {
83-
String path = request.getPathInfo();
84-
if (path.indexOf("/rest/web") != 0) {
85-
path = path.substring(path.indexOf("/rest/web"));
86-
}
87-
return path.substring("/rest/web/".length());
82+
String getFileName(HttpServletRequest request) throws IOException {
83+
String path =
84+
URLDecoder.decode(request.getRequestURI(), "UTF-8")
85+
.substring(request.getContextPath().length())
86+
.replace(File.separatorChar, '/');
87+
int index = path.indexOf("/rest/web/");
88+
return index < 0 ? null : path.substring(index + "/rest/web/".length());
8889
}
8990

9091
@RequestMapping(value = "/web/**", method = RequestMethod.GET)
91-
ResponseEntity<?> doGet(HttpServletRequest request, HttpServletResponse response) {
92-
final String filename;
93-
try {
94-
filename = URLDecoder.decode(getFileName(request), "UTF-8");
95-
} catch (UnsupportedEncodingException e1) {
96-
throw new IllegalStateException(
97-
"Could not decode encoding UTF-8", e1); // Should never happen
92+
ResponseEntity<?> doGet(HttpServletRequest request, HttpServletResponse response)
93+
throws IOException {
94+
final String filename = getFileName(request);
95+
if (filename == null || filename.isEmpty()) {
96+
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
9897
}
9998

10099
// Just to make sure we don't allow access to arbitrary resources

geowebcache/rest/src/test/java/org/geowebcache/rest/controller/ByteStreamControllerTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
package org.geowebcache.rest.controller;
1616

1717
import static org.hamcrest.Matchers.startsWith;
18+
import static org.junit.Assume.assumeTrue;
1819
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
1920
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
2021
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
2122

23+
import org.apache.commons.lang3.SystemUtils;
2224
import org.junit.Before;
2325
import org.junit.Rule;
2426
import org.junit.Test;
@@ -100,4 +102,18 @@ public void testBackreference2() throws Exception {
100102
mockMvc.perform(get("/rest/web/foo/../../../shouldnt/access/test.png"))
101103
.andExpect(status().is4xxClientError());
102104
}
105+
106+
@Test
107+
public void testBackreferenceWindows() throws Exception {
108+
assumeTrue(SystemUtils.IS_OS_WINDOWS);
109+
mockMvc.perform(get("/rest/web/..\\..\\shouldnt/access/test.png"))
110+
.andExpect(status().is4xxClientError());
111+
}
112+
113+
@Test
114+
public void testBackreferenceWindows2() throws Exception {
115+
assumeTrue(SystemUtils.IS_OS_WINDOWS);
116+
mockMvc.perform(get("/rest/web/foo\\..\\..\\..\\shouldnt/access/test.png"))
117+
.andExpect(status().is4xxClientError());
118+
}
103119
}

0 commit comments

Comments
 (0)