Skip to main content

Lack of data validation - Path Traversal

Need

Implementation of robust data validation and input sanitization mechanisms

Context

  • Usage of PHP for server-side scripting and web development
  • Usage of PHP for server-side scripting and web development

Description

Non compliant code

<?php
$file = $_GET['file'];
$content = file_get_contents('/var/www/html/app/storage/' . $file);
echo $content;
?>

In the above code, we are using PHP to construct a file path using the 'file' parameter from the GET request. This 'file' parameter is directly concatenated to the base directory path '/var/www/html/app/storage/'. The problem here is that there is no validation or sanitization performed on this 'file' parameter before it is used to create a file path.

This lack of validation/sanitization means that an attacker could potentially manipulate the 'file' parameter to traverse directories that they should not have access to. For example, by sending a GET request with 'file' parameter set as '../../etc/passwd', the attacker could read sensitive system files. This is a classic example of a Path Traversal vulnerability.

The software does not neutralize or validate the special elements within the pathname that is constructed from external input, leading to potential unauthorized access to files and directories.

Steps

  • Validate the input: Ensure that the 'file' parameter is a valid filename and does not contain any directory traversal characters or sequences.
  • Sanitize the input: Remove or replace any invalid characters or sequences from the 'file' parameter.
  • Use a whitelist approach: Only allow known good files to be accessed.
  • Use built-in functions to secure file paths: Use functions like 'realpath()' and 'basename()' to resolve the path and get the filename respectively, which can help to prevent directory traversal attacks.
  • Limit the permissions: Restrict the permissions of the directory to read-only, to prevent any unauthorized modifications.
  • Implement error handling: If an invalid file is requested, the application should handle this gracefully, without revealing any sensitive information.

Compliant code

<?php
$file = $_GET['file'];
$file = basename($file);
if(!preg_match('/^[a-z0-9_\\-.]+$/i', $file)) {
die('Invalid file name!');
}
$allowed_files = ['file1.txt', 'file2.txt', 'file3.txt']; // Add your allowed files here
if(!in_array($file, $allowed_files)) {
die('File not allowed!');
}
$path = realpath('/var/www/html/app/storage/' . $file);
if(strpos($path, '/var/www/html/app/storage/') !== 0) {
die('File not found!');
}
$content = file_get_contents($path);
echo $content;
?>

The above code fixes the path traversal vulnerability by implementing several security measures:

  1. Input Validation: The 'file' parameter is validated using a regular expression to ensure it only contains alphanumeric characters, underscores, hyphens, and periods. If the validation fails, the script terminates with an error message.

  2. Input Sanitization: The 'basename()' function is used to get the filename from the 'file' parameter, removing any directory traversal sequences.

  3. Whitelist Approach: An array of allowed files is defined, and the 'file' parameter is checked against this list. If the file is not in the list, the script terminates with an error message.

  4. Secure File Paths: The 'realpath()' function is used to resolve the path of the file, which helps to prevent directory traversal attacks. The resolved path is then checked to ensure it is within the intended directory. If it is not, the script terminates with an error message.

  5. Error Handling: If any of the checks fail, the script terminates with an appropriate error message, without revealing any sensitive information.

References