|
18 | 18 | import java.lang.annotation.Annotation;
|
19 | 19 | import java.lang.reflect.Field;
|
20 | 20 | import java.nio.charset.StandardCharsets;
|
| 21 | +import java.nio.file.Path; |
| 22 | +import java.nio.file.Paths; |
21 | 23 | import java.util.Collections;
|
22 | 24 | import java.util.HashMap;
|
23 | 25 | import java.util.List;
|
@@ -116,30 +118,27 @@ public final void doFilter(ServletRequest request, ServletResponse response, Fil
|
116 | 118 | // (the "/initfilter" part is needed so that the openmrs_static_context-servlet.xml file doesn't
|
117 | 119 | // get instantiated early, before the locale messages are all set up)
|
118 | 120 | if (servletPath.startsWith("/images") || servletPath.startsWith("/initfilter/scripts")) {
|
119 |
| - servletPath = servletPath.replaceFirst("/initfilter", "/WEB-INF/view"); // strip out the /initfilter part |
| 121 | + // strip out the /initfilter part |
| 122 | + servletPath = servletPath.replaceFirst("/initfilter", "/WEB-INF/view"); |
120 | 123 | // writes the actual image file path to the response
|
121 |
| - File file = new File(filterConfig.getServletContext().getRealPath(servletPath)); |
| 124 | + Path filePath = Paths.get(filterConfig.getServletContext().getRealPath(servletPath)).normalize(); |
| 125 | + Path fullFilePath = filePath; |
122 | 126 | if (httpRequest.getPathInfo() != null) {
|
123 |
| - file = new File(file, httpRequest.getPathInfo()); |
| 127 | + fullFilePath = fullFilePath.resolve(httpRequest.getPathInfo()); |
| 128 | + if (!(fullFilePath.normalize().startsWith(filePath))) { |
| 129 | + log.warn("Detected attempted directory traversal in request for {}", httpRequest.getPathInfo()); |
| 130 | + return; |
| 131 | + } |
124 | 132 | }
|
125 | 133 |
|
126 |
| - InputStream imageFileInputStream = null; |
127 |
| - try { |
128 |
| - imageFileInputStream = new FileInputStream(file); |
| 134 | + try (InputStream imageFileInputStream = new FileInputStream(fullFilePath.normalize().toFile())) { |
129 | 135 | OpenmrsUtil.copyFile(imageFileInputStream, httpResponse.getOutputStream());
|
130 | 136 | }
|
131 | 137 | catch (FileNotFoundException e) {
|
132 |
| - log.error("Unable to find file: " + file.getAbsolutePath()); |
| 138 | + log.error("Unable to find file: {}", filePath, e); |
133 | 139 | }
|
134 |
| - finally { |
135 |
| - if (imageFileInputStream != null) { |
136 |
| - try { |
137 |
| - imageFileInputStream.close(); |
138 |
| - } |
139 |
| - catch (IOException io) { |
140 |
| - log.warn("Couldn't close imageFileInputStream: " + io); |
141 |
| - } |
142 |
| - } |
| 140 | + catch (IOException e) { |
| 141 | + log.warn("An error occurred while handling file {}", filePath, e); |
143 | 142 | }
|
144 | 143 | } else if (servletPath.startsWith("/scripts")) {
|
145 | 144 | log.error(
|
@@ -193,7 +192,7 @@ private void initializeVelocity() {
|
193 | 192 | velocityEngine.init(props);
|
194 | 193 | }
|
195 | 194 | catch (Exception e) {
|
196 |
| - log.error("velocity init failed, because: " + e); |
| 195 | + log.error("velocity init failed, because: {}", e, e); |
197 | 196 | }
|
198 | 197 | }
|
199 | 198 | }
|
|
0 commit comments