CVE-2018-18434: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') (CWE-22)
value: An issue was discovered in litemall 0.9.0. Arbitrary file download is possible via ../ directory traversal in linlinjava/litemall/wx/web/WxStorageController.java in the litemall-wx-api component.
CWE description: The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
CVSS v3 base score: 7.5
Published: 2018-10-17T06:29Z
Repository: https://github.com/linlinjava/litemall
Language: Java
Files changed: litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java
Commit date: 2018-10-16 13:46:54 +0800
Commit message: fix[litemall-wx-api]: 修复文件路径中包含"../"带来的安全问题

Diff: diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java
index ddb3701..538a70e 100644
--- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java
+++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java
@@ -56,34 +56,41 @@ public class WxStorageController {
 
     @GetMapping("/fetch/{key:.+}")
     public ResponseEntity<Resource> fetch(@PathVariable String key) {
         LitemallStorage litemallStorage = litemallStorageService.findByKey(key);
         if (key == null) {
-            ResponseEntity.notFound();
+            return ResponseEntity.notFound().build();
+        }
+        if(key.contains("../")){
+            return ResponseEntity.badRequest().build();
         }
         String type = litemallStorage.getType();
         MediaType mediaType = MediaType.parseMediaType(type);
 
         Resource file = storageService.loadAsResource(key);
         if (file == null) {
-            ResponseEntity.notFound();
+            return ResponseEntity.notFound().build();
         }
         return ResponseEntity.ok().contentType(mediaType).body(file);
     }
 
     @GetMapping("/download/{key:.+}")
     public ResponseEntity<Resource> download(@PathVariable String key) {
         LitemallStorage litemallStorage = litemallStorageService.findByKey(key);
         if (key == null) {
-            ResponseEntity.notFound();
+            return ResponseEntity.notFound().build();
+        }
+        if(key.contains("../")){
+            return ResponseEntity.badRequest().build();
         }
+
         String type = litemallStorage.getType();
         MediaType mediaType = MediaType.parseMediaType(type);
 
         Resource file = storageService.loadAsResource(key);
         if (file == null) {
-            ResponseEntity.notFound();
+            return ResponseEntity.notFound().build();
         }
         return ResponseEntity.ok().contentType(mediaType).header(HttpHeaders.CONTENT_DISPOSITION,
                 "attachment; filename=\"" + file.getFilename() + "\"").body(file);
     }
 

Vulnerable code:             ResponseEntity.notFound();
            ResponseEntity.notFound();
            ResponseEntity.notFound();
            ResponseEntity.notFound();
Fixed code:             return ResponseEntity.notFound().build();
        }
        if(key.contains("../")){
            return ResponseEntity.badRequest().build();
            return ResponseEntity.notFound().build();
            return ResponseEntity.notFound().build();
        }
        if(key.contains("../")){
            return ResponseEntity.badRequest().build();

            return ResponseEntity.notFound().build();