#901·eladmin

[Security]Directory Traversal in File Upload Path Construction Allows Write Outside the Intended Upload Directory

Author: v9d0gCreated May 20, 2026Updated Jun 4, 2026

Affected Component

me.zhengjie.rest.LocalStorageController.createFile(...) me.zhengjie.service.impl.LocalStorageServiceImpl.create(...) me.zhengjie.utils.FileUtil.upload(...)

Description

The upload flow partially sanitizes the user-controlled filename, but the final destination path is constructed using a suffix derived from the raw MultipartFile.getOriginalFilename() value. That suffix is not sanitized before being concatenated into the final filesystem path.

As a result, a crafted filename can inject path traversal elements into the computed destination path. The destination File is then normalized with getCanonicalFile(), which may resolve the traversal and place the uploaded file outside the intended upload directory.

Affected Code Path

LocalStorageController.createFile(name, file) → LocalStorageServiceImpl.create(name, multipartFile) → FileUtil.upload(multipartFile, filePath) → MultipartFile.transferTo(dest)

Root Cause

In FileUtil.upload(...):

String name = getFileNameNoEx(verifyFilename(file.getOriginalFilename()));
String suffix = getExtensionName(file.getOriginalFilename());
String fileName = name + nowStr + "." + suffix;
String path = filePath + fileName;
File dest = (new File(path)).getCanonicalFile();
file.transferTo(dest);

verifyFilename() is applied only to name. suffix is extracted from the raw filename and is not sanitized.

Security Impact

An authenticated attacker with permission to access the upload endpoint may be able to write a file outside the intended upload directory. Depending on deployment permissions and target location, this can lead to:

  • arbitrary file write within the application’s writable scope
  • overwrite of application-controlled files
  • further compromise if the written file is executable or consumed by another component

POC

------WebKitFormBoundaryOZfP2Gqc31W0qyeS
Content-Disposition: form-data; name="file"; filename="x/../../../../evil.ai."
Content-Type: text/javascript

hello

------WebKitFormBoundaryOZfP2Gqc31W0qyeS--

The file was eventually uploaded to the C drive.