Skip to main content

Local file inclusion

Need

Prevention of unauthorized access to local files

Context

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

Description

Non compliant code

<?php
// vulnerable code
$file = $_GET['file'];
include($file);
?>

In this piece of code, the application takes a file name from a user through a GET request and includes that file in the current script using the include() function.

The $_GET['file'] variable is directly used without any validation or sanitization. This means an attacker can manipulate the 'file' parameter in the GET request to include any file from the server's file system that the script has access to.

For example, an attacker can use a path like http://example.com/vulnerable.php?file=../../../../etc/passwd to read sensitive files from the server. This is known as Path Traversal or Local File Inclusion (LFI) vulnerability.

The attacker can also include malicious scripts located on the server to execute arbitrary code, making the system susceptible to Remote Code Execution (RCE).

This vulnerability can lead to serious security issues including information disclosure, data manipulation, and in some cases, complete system compromise.

Steps

  • Validate the input: Ensure that the input provided by the user is valid and expected. This can be done by using a whitelist of allowed values.
  • Avoid using user input directly: Instead of directly using user input in sensitive functions like 'include', use it to select from predefined values.
  • Use absolute paths: Instead of using relative paths, use absolute paths. This can prevent the user from accessing files outside of the intended directory.
  • Disable error reporting: If an error occurs, the path of the file is often revealed, which can provide useful information to an attacker. Therefore, disable error reporting in the production environment.
  • Update your PHP version: Older versions of PHP are more vulnerable to Local File Inclusion attacks. Therefore, keep your PHP version updated.

Compliant code

<?php
// fixed code
$file = $_GET['file'];

// Whitelist of allowed files
$allowed_files = ['file1.php', 'file2.php', 'file3.php'];

if (in_array($file, $allowed_files)) {
include(__DIR__ . '/' . $file);
} else {
// Handle the error
echo "File not found!";
}
?>

The fixed code now includes a whitelist of allowed files. This is done by creating an array $allowed_files that contains the names of all the files that are allowed to be included.

When a GET request is made, the $file variable is set to the value of the 'file' parameter in the request. Instead of directly including this file, the code now checks if the requested file is in the $allowed_files array using the in_array() function.

If the requested file is in the array, it is included using the include() function. However, instead of using the relative path provided by the user, the code uses the __DIR__ magic constant to get the absolute path of the current directory and appends the filename to it. This ensures that only files in the current directory can be included, preventing the user from accessing files outside of the intended directory.

If the requested file is not in the $allowed_files array, an error message is displayed. This could be replaced with any error handling code appropriate for your application.

This code also assumes that error reporting is disabled in the production environment, as revealing the path of the file in an error message could provide useful information to an attacker.

Finally, it's important to keep your PHP version updated to protect against Local File Inclusion attacks, as older versions of PHP are more vulnerable to these types of attacks.

References