Common Weakness Enumeration CWE-22, commonly referred to as “path traversal”, is a vulnerability where an application does not appropriately restrict the paths that users can access through user-supplied input. This may allow attackers to access directories and files outside the intended directory, resulting in unauthorized access and potential system compromise. This vulnerability is particularly significant in Java applications due to their ubiquitous use of file processing and web resources. This post deals with the nature of CWE-22, its impact, exploitation methods, and most importantly the strategies to mitigate such vulnerabilities in Java applications.
Advertisement
Sven has been programming Java for over 15 years in industrial projects since 1996 and in industries such as automotive, aerospace, insurance, banking, United Nations and the World Bank around the world. For over 10 years he has been a speaker at conferences and community events from the US to New Zealand, worked as developer advocate for JFrog and Vaadin and regularly writes articles for IT magazines and technology portals. Apart from his core subject of Core Java, he deals with TDD and secure coding practices.
CWE-22 at a glance
CWE-22 is classified as “Improper restriction of pathname to restricted directory (path traversal)”. The vulnerability occurs when an application uses user input to create a path without proper validation or sanitization, allowing someone to specify paths that go outside the intended directory. Sequences such as ../ can be used to move up one level in the directory structure.
For example, a typical Java code snippet that reads a file based on user input looks like this:
String fileName = request.getParameter("file");
File file = new File("/var/www/uploads/" + fileName);
FileInputStream fis = new FileInputStream(file);
is the parameter fileName
If not properly verified, an attacker can manipulate /var/www/uploads/ to access files outside the directory, such as: B. /etc/passwd, path traversal sequence (`. ./ Using ../etc/passwd`).
Impact of CWE-22
The impact of CWE-22 can be severe, ranging from unauthorized access to sensitive files to complete system compromise. Possible effects include:
- Exposure of sensitive information: Attackers can access sensitive files such as configuration files, passwords, and personal information.
- Data integrity compromise: Attackers can modify files, potentially resulting in data corruption or modification of critical application files.
- Denial of service (DoS): Attackers can disrupt normal operations by accessing and modifying system files.
- Arbitrary code execution: In extreme cases, if attackers gain access to executable files or scripts they can execute arbitrary code.
exploitation techniques
To exploit a path traversal vulnerability, an attacker typically uses special characters and patterns in the input to navigate the file system. Some standard techniques are:
- Dot-dot-slash (../): The most common method, where the attacker uses ../ to move up the directory structure.
- Encoded characters: Attackers can use URL encoding (%2e%2e%2f) or other encoding schemes to bypass simple input filters.
- Zero byte injection: Null bytes (%00) are sometimes used to terminate strings early, effectively ignoring any enclosing extensions or path components.
Damage Control Strategies in Java

Mitigating the potential threats of CWE-22 in Java requires a combination of safe coding practices, input validation, and proper use of APIs. The recommended strategies for this are:
demonetization and normalization
Make sure file paths are normalized before use. Java provides path normalization methods that can help mitigate traversal attacks.
import java.nio.file.Paths;
import java.nio.file.Path;
public File getFile(String fileName) throws IOException {
Path basePath = Paths.get("/var/www/uploads/");
Path filePath = basePath.resolve(fileName).normalize();
if (!filePath.startsWith(basePath)) {
throw new SecurityException("Attempted path traversal attack detected");
}
return filePath.toFile();
}
Input validation and sanitization
Strictly validate user input. Reject any input that contains potentially malicious patterns such as ../, URL encoded sequences, or other traversal patterns.
public String sanitizeFileName(String fileName) {
if (fileName == null
|| fileName.contains("..")
|| fileName.contains("/")
|| fileName.contains("\\")) {
throw new IllegalArgumentException("Invalid file name");
}
return fileName;
}
whitelist approach
Use whitelisting to validate file names against a set of acceptable values ​​or patterns. This may be more effective than blacklisting known destructive patterns.
public boolean isValidFileName(String fileName) {
return fileName.matches("(a-zA-Z0-9._-)+");
}
Security Manager and Permissions
Use Java’s security manager to restrict access to the file system. It adds an additional layer of security by enforcing access control policies at runtime. However, the corresponding Java version should be taken into account here, as SecurityManager will be dropped in one of the future JDK versions.
System.setSecurityManager(new SecurityManager());
file access control
Restrict file permissions on the server to limit access to only essential files and directories. This reduces the impact of potential exploits. The web service process should run under a defined user whose rights are limited to what is absolutely necessary.
Logging and monitoring
Implement comprehensive logging and monitoring to detect and respond to suspicious activity. Logs should contain enough detail to track potential exploit attempts.
import java.util.logging.Logger;
public class FileAccessLogger {
private static final Logger LOGGER =
Logger.getLogger(
FileAccessLogger.class.getName());
public void logAccessAttempt(String fileName) {
LOGGER.warning("Attempted access to file: " + fileName);
}
}
Case Study: A Vulnerable Java Application
Let us consider a hypothetical case study to illustrate the application of the therapeutic strategies mentioned. Suppose we have a simple Java web application that allows users to download files from a server.
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileName = request.getParameter("file");
File file = new File("/var/www/uploads/" + fileName);
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename=\"" + file.getName() + "\"");
byte() buffer = new byte(4096);
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}
fis.close();
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
}
It reads servlet parameters file
Creates another one by request File
-object. Without proper verification, an attacker can exploit this to download arbitrary files from the server.
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileName = sanitizeFileName(request.getParameter("file"));
Path basePath = Paths.get("/var/www/uploads/");
Path filePath = basePath.resolve(fileName).normalize();
if (!filePath.startsWith(basePath)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid file path");
return;
}
File file = filePath.toFile();
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename=\"" + file.getName() + "\"");
byte() buffer = new byte(4096);
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}
fis.close();
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
private String sanitizeFileName(String fileName) {
if (fileName == null
|| fileName.contains("..")
|| fileName.contains("/")
|| fileName.contains("\\")) {
throw new IllegalArgumentException("Invalid file name");
}
return fileName;
}
}
Provides method in safe version sanitizeFileName
This ensures that file names are free of traversal sequences, and that paths are normalized and checked to prevent directory traversal.
CWE-22 (Path Traversal) is a serious vulnerability that can have serious consequences if not adequately mitigated. In Java applications, it is important to employ a combination of secure coding practices, input validation, canonicalization, and access controls to protect against this threat. By understanding the nature of CWE-22 and implementing strong security measures, developers can significantly reduce the risk of unauthorized file access and protect their applications from potential exploitation.
