This skill focuses on determining at the source code level whether a "file operation vulnerability holds", with the core being to verify path controllability, filename controllability, and content controllability. Constructing runtime exploitation techniques such as upload bypass payloads and directory traversal exploit chains falls under the scope of the corresponding black-box exploit skill.
In-depth reference
- Dangerous pattern / secure pattern code comparison / EVID evidence examples for 5 types of file vulnerabilities → references/file-vuln-patterns.md
Sink classification decision tree
Based on the type of Sink function encountered, enter different audit branches:
| Sink function | Branch | Typical severity |
|---|---|---|
MultipartFile.transferTo() / Part.write() |
File upload | Critical-High |
FileInputStream / Files.readAllBytes() / new File(path) / ClassLoader.getResourceAsStream() |
File read | High-Medium |
FileOutputStream / Files.write() / FileWriter |
File write | Critical-High |
ZipInputStream.getNextEntry() / ZipFile.entries() |
Archive extraction | High |
File.delete() / Files.delete() |
File deletion | Medium |
File upload audit key points
The essence of an upload vulnerability is the simultaneous satisfaction of three elements: executable extension + web-reachable storage path + not renamed/content sanitized.
- MultipartFile:
file.transferTo(new File(dir + file.getOriginalFilename()))—getOriginalFilename()Returns the client's original filename, which may contain../path traversal or a malicious extension - Servlet Part:
part.write(uploadPath + fileName)— check whetherfileNamecomes frompart.getSubmittedFileName()and is not sanitized - ContentType validation vs extension validation:
file.getContentType()comes from the client HTTP header and is completely forgeable; an extension whitelist is more reliable but requirestoLowerCase()handling - Storage path controllability:
../in the filename escapes the upload directory,Paths.get(dir, fileName).normalize()requires prefix verification afterward - Spring multipart-config:
spring.servlet.multipart.location/max-file-size/max-request-sizeconfiguration affects upload behavior, check whether the restrictions are reasonable - File header Magic bytes validation: real type detection requires reading the file header bytes (such as
ImageIO.read()or Apache Tika), rather than trusting Content-Type
File read audit key points
Path traversal is the core of file read vulnerabilities;../ and its variants can escape the expected directory:
- Path traversal
../:new FileInputStream("/data/" + userPath)— user input../../etc/passwdreads arbitrary files - NIO secure pattern:
Path resolved = baseDir.resolve(userInput).normalize(); if (!resolved.startsWith(baseDir)) throw ...—normalize()eliminates../,startsWith()verify prefix - URL encoding bypass:
%2e%2e%2f(../), double encoding%252e%252e%252f— check whether the framework automatically decodes before passing into the path - ClassLoader.getResourceAsStream: classpath reading is restricted by the ClassLoader sandbox and usually cannot traverse to arbitrary paths on the file system, but can read sensitive configuration within the classpath
- Spring Resource path:
classpath:protocol is limited to within the classpath,file:protocol can access the file system — check whether the protocol is user-switchable
File write audit key points
A write vulnerability requires: controllable path + controllable content + the write path can be executed by the web container.
- WebShell write:
Files.write(Paths.get(dir + filename), content.getBytes())— when both path and content are controllable, writing.jspto the web root achieves RCE - Configuration file overwrite: overwriting
application.yml/application.propertiesmodifies configurations such as data sources and redirects; overwritingweb.xmlAdd malicious Servlet mapping - Log injection to write a webshell: Logging framework records user input → log file path is predictable → combined with file inclusion or directly writing JSP content to the log
- Template file overwrite: Thymeleaf / FreeMarker template directory is writable → overwrite template to inject SSTI payload → triggered on next render
- Secure mode: Path whitelist + content type validation + file storage outside the web root + minimized write permissions
Archive extraction audit points
Zip Slip is the most classic vulnerability in archive extraction; malicious archive entry names contain ../ leading to arbitrary path write:
- ZipEntry.getName() contains
../:new File(destDir, entry.getName())— entry names such as../../webapps/ROOT/shell.jspare written directly to the web directory - Secure mode (Canonical Path validation): Before extraction, obtain
file.getCanonicalPath()anddestDir.getCanonicalPath(), and verify that the file path is prefixed by the target directory - TarInputStream / GzipInputStream: Similar risk; tar entry names can likewise contain path traversal
- File overwrite: Even without traversing directories, a malicious archive can overwrite existing files in the same directory (configuration files, library files)
File deletion audit points
- Path traversal deletion:
new File(dir + userInput).delete()— user input../../important.confdeletes critical files - TOCTOU race: The time window between checking permissions → performing deletion; an attacker can replace the target with a symbolic link pointing to a sensitive file
- Symbolic link following:
Files.delete(path)deletes the link target rather than the link itself (depending on the implementation),File.delete()deletes only the link
Detection checklist
- All file-type EVID_* evidence points have been reviewed one by one
- The file name sanitization method of the upload function has been confirmed (UUID rename vs original file name vs whitelist extension)
- Whether the upload storage path is inside the web root and whether it can be accessed directly via URL has been verified
- ContentType validation vs file header Magic bytes validation methods have been distinguished
- Traversal protection for file read paths has been checked (normalize + startsWith pattern)
- The path and content sources of file writes have been traced, and whether writable executable locations exist has been confirmed
- Entry name validation in the archive extraction function has been checked (Canonical Path validation)
- Path validation and symbolic link risks in file deletion operations have been assessed
- Points with insufficient filtering have been given bypass ideas or marked "to be verified"
- Severity scoring uses a unified formula, consistent with the pipeline