Skip to main content

Insecure File Management

Fixing Insecure File Management

About File Inclusion

What is File Inclusion?

File inclusion is a type of security vulnerability that allows an attacker to include files on a server or application that should not be accessible. This vulnerability occurs when a web application does not properly validate user input, such as file names or paths, and allows file inclusion sequences to be passed through the input.

There are two main types of file inclusion vulnerabilities:

  • Local File Inclusion (LFI): LFI occurs when a web application allows a user to include a local file on the server that should not be accessible. An attacker can exploit this vulnerability by providing a malicious file path, which the web application includes without proper validation. The attacker can use LFI to access sensitive files, such as password files or configuration files, and potentially execute arbitrary code on the server.

  • Remote File Inclusion (RFI): RFI occurs when a web application allows a user to include a file from a remote server. An attacker can exploit this vulnerability by providing a malicious file path to a file hosted on a remote server. The attacker can use RFI to include a file that contains malicious code, such as a remote shell, which can be executed on the server.

Both LFI and RFI vulnerabilities can be exploited to gain unauthorized access to sensitive data or to execute arbitrary code on a server, which can lead to various security incidents such as data breaches, system compromises, or disruption of services.

What is the impact of File Inclusion?

The impact of a file inclusion vulnerability can lead to unauthorized access to sensitive files and data on a server or application. This can include files containing passwords, user data, or other confidential information.

An attacker who successfully exploits a file inclusion vulnerability can gain access to sensitive data, modify or delete files, and potentially execute arbitrary code or perform other malicious actions.

The impact of a file inclusion vulnerability can vary depending on the nature of the files and data that are accessed, as well as the specific context of the system or application being targeted.

In some cases, a file inclusion attack may have little impact beyond revealing the existence of certain files, while in other cases, it can have severe consequences for the confidentiality, integrity, and availability of the system or application.

How to prevent File Inclusion?

To prevent file inclusion vulnerabilities, it is important to properly validate and sanitize user input, and use secure coding practices.

Here are some steps that can help prevent file inclusion attacks:

  • Validate user input: Always validate and sanitize user input, especially file names and paths. Ensure that user input only contains expected characters and that any special characters are properly escaped or removed.
  • Use secure coding practices: Use secure coding practices, such as enforcing strict file permissions and preventing the execution of user-controlled input as code. Use libraries and frameworks that have built-in protection against file inclusion attacks.
  • Use an allow list: Use an allow list of permitted file names or directories and reject any input that does not match the allow list.
  • Implement access controls: Implement access controls to restrict user access to files and directories based on roles and permissions.
  • Monitor and log: Monitor and log all file system access to detect any suspicious activity or attempts to access files or directories outside of the expected range.

By following these steps, you can help prevent file inclusion vulnerabilities and reduce the risk of unauthorized access to sensitive files and data.

References

Taxonomies

Explanation & Prevention

Training

Option A: Properly Process User Input

  1. Go through the issues that GuardRails identified in the PR/MR

  2. A vulnerable example taken from DVWA is shown below:

    <?php
    if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
    // Can we move the file to the upload folder?
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
    // No
    $html .= '<pre>Your image was not uploaded.</pre>';
    }
    else {
    // Yes!
    $html .= "<pre>{$target_path} succesfully uploaded!</pre>";
    }
    }
    ?>
  3. A secure version of this is also taken from DVWA:

    <?php
    if( isset( $_POST[ 'Upload' ] ) ) {
    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
    // Where are we going to be writing to?
    $target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
    $target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
    $temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
    $temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
    // Is it an image?
    if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) &&
    ( $uploaded_size < 100000 ) &&
    ( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
    getimagesize( $uploaded_tmp ) ) {
    // Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
    if( $uploaded_type == 'image/jpeg' ) {
    $img = imagecreatefromjpeg( $uploaded_tmp );
    imagejpeg( $img, $temp_file, 100);
    }
    else {
    $img = imagecreatefrompng( $uploaded_tmp );
    imagepng( $img, $temp_file, 9);
    }
    imagedestroy( $img );
    // Can we move the file to the web root from the temp folder?
    if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {
    // Yes!
    $html .= "<pre><a href='${target_path}${target_file}'>${target_file}</a> successfully uploaded!</pre>";
    }
    else {
    // No
    $html .= '<pre>Your image was not uploaded.</pre>';
    }
    // Delete any temp files
    if( file_exists( $temp_file ) )
    unlink( $temp_file );
    }
    else {
    // Invalid file
    $html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
    }
    ?>
  4. Test it

  5. Ship it 🚢 and relax 🌴

Option B: Migrate to Cloud Storage

  1. Nowadays, there is rarely a need to allow users to interact with local files
  2. A better alternative is storing files in dedicated systems, such as AWS S3
  3. More information about the PHP AWS S3 SDK can be found here
  4. Other cloud providers offer similar options