Description
Hua Li opened SPR-13662 and commented
Note
I found the issue in the latest code of master branch here: https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java
I assume it applies to the latest 4.2.2 version.
getOriginalFilename() tries to strip file path from while file path name string and returns only the file name part.
It has been coded to be adaptive - looking for Linux path separator char "/" first, if fail then looking for Windows path separator char "".
But this adaptive logic is buggy - if Spring is running on a Windows computer and if attacker provides a path name like "/......\malicious_directory\malicious_file" then the getOriginalFilename() method will return "......\malicious_directory\malicious_file" which is not a bare file name but contains both path and file name.
Then if application layer code assumes it is a bare file name and use it as a bare file name, critical path traversal issue can happen.
I think the right logic is - using File.separator to find and strip the path and get bare file name.
Affects: 3.2.15, 4.1.8, 4.2.2
Issue Links:
- StringUtils.getFilename(String) should parse any kind of file separator [SPR-5284] #9957 StringUtils.getFilename(String) should parse any kind of file separator
- CommonsMultipartFile.getOriginalFilename() should be able to preserve header-specified filename as-is [SPR-14613] #19180 CommonsMultipartFile.getOriginalFilename() should be able to preserve header-specified filename as-is