Improper handling of file paths
can lead to security vulnerabilities known as directory traversal attacks
. These vulnerabilities allow an attacker to access arbitrary files on the server.
What is a Directory Traversal Attack?
A directory traversal attack occurs when an attacker manipulates file paths to access files outside the intended directory. For instance, if an application uses a user-provided file path without validation, an attacker could use a path like ../../etc/passwd
to access sensitive files on the server.
Example of a Directory Traversal Attack:
- Vulnerable Code:
const filePath = `public/uploads/${req.params.fileName}`;
Imagine you have a file download function that allows users to download files by providing an id
. The application might construct the file path directly from the user input.
- Malicious Input:
/public/uploads/../../secret.txt
Here an attacker could provide a malicious input like ../../secret.txt
, leading to an unintended file access.
- Consequences:
If the application does not validate this input, it could expose sensitive files, such as configuration files or user data, to the attacker.
Example of preventing such kind of attacks
import path from 'path';
import fs from 'fs/promises';
import { RequestHandler, NextFunction } from 'express';
// Point: 1
const BASE_DIRECTORY = path.resolve(__dirname, 'public/uploads');
export const downloadAttachment: RequestHandler = async (req, res, next: NextFunction) => {
// Point: 2
const { fileName } = req.params;
// Point: 3
const filePath = path.join(BASE_DIRECTORY, fileName);
const resolvedPath = path.resolve(filePath);
// Point: 4
if (!resolvedPath.startsWith(BASE_DIRECTORY)) {
return res.status(400).json({ message: "Invalid file path" });
}
try {
// Point: 5
await fs.access(resolvedPath);
// Point: 6
res.download(resolvedPath, path.basename(fileName), (err) => {
if (err) {
return next(err);
}
});
} catch {
// Point: 7
return res.status(404).json({ message: "File not found" });
}
};
Key Points Explained:
Base Directory Definition: Establishes a fixed directory for file uploads to restrict access.
Extracting File Name: Retrieves the requested file name from the URL parameters.
File Path Construction: Combines the base directory with the requested file name to create a full path.
Path Validation: Ensures that the resolved file path is within the designated base directory to prevent unauthorized access.
File Existence Check: Asynchronously checks if the file exists at the constructed path.
File Download Handling: Initiates the file download and handles any errors that may occur during the process.
Error Handling for Missing Files: Sends a 404 response if the requested file does not exist.
Acknowledgment: This document references information from PortSwigger Web Security and ChatGPT.
Top comments (0)