Working with files is a common requirement in many applications, but it also introduces several potential security vulnerabilities. In this article, we will explore how to securely work with files in your application.
Let’s review common vulnerabilities and mitigations when working file files.
TLDR
- File Inclusions and Path Traversal vulnerabilities are the results of insecure accessing files
- Avoid accessing file paths that are built with user-provided input
- If you must use inputs from users in file paths, use a strict whitelist for allowed user inputs and reject non-compliant inputs
- Use libraries to detect if the file you’re going to access is in the intended directory (e.g.
realpath()
in PHP and NodeJs) - When creating files (e.g. file uploads) set a reasonable file size limit
- When writing user-provided content, make sure the content type is what you expect
- When creating files, make sure they don’t have execution permission
- When creating files, make sure they’re not publicly accessible
File Inclusion Vulnerability
File inclusion vulnerability is a type of web vulnerability that occurs when an application allows a user to include a file in the output of a web page without properly validating or sanitizing the user input.
There are two types of file inclusion vulnerabilities: Local File Inclusion (LFI) and Remote File Inclusion (RFI).
LFI occurs when an attacker can include a file from the local file system of the server. This can allow the attacker to view sensitive files or execute arbitrary code on the server.
RFI occurs when an attacker can include a file from a remote server. This can allow the attacker to execute arbitrary code on the server or steal sensitive information.
For example, consider the following vulnerable PHP code:
$module = $_GET['module'];
include $module;
This code retrieves a value from the URL query string using the $_GET
superglobal, specifically the “module” parameter. The retrieved value is then used as the file path to include a PHP file using the include
statement. This means that the contents of the specified file will be included in the current script at the point where the include
statement appears.
However, this code can be potentially dangerous to both LFI and RFI.
In the above PHP code example, a user can pass any file name or URL as the module
parameter. For instance, an attacker can host a PHP script on their server and pass its URL, like http://attackerhost/phpscript.txt
, in the module parameter and execute arbitrary commands on the target system.
In PHP, for example, file inclusion vulnerabilities are often caused by the use of the include
or require
functions without proper input validation. Similarly, in JSP, file inclusion vulnerabilities can occur when the include
or jsp:include
tags are used without proper input validation. Using Server.Execute
or Server.Transfer
in ASP also can create file inclusion vulnerabilities.
Local File Download
Suppose an application has a file download functionality that allows users to download a file from the server. The application takes a file name as a parameter and returns the file contents to the user. If the application does not validate the file name parameter and allows users to download any file on the server, an attacker can exploit this vulnerability by passing a sensitive file name as the parameter. This is called Local File Download or Local File Disclosure vulnerability.
In our example, if the user passes /etc/passwd
as a module parameter, the content of passwd
file is displayed to the user.
Local file download is a very common vulnerability and can be found in any programming language.
Prevent File Inclusion Vulnerabilities
Follow below best practices to mitigate File Inclusion vulnerabilities:
- Do not include or open files that are built using user-provided data
- If you must use inputs from users in file paths, use a strict whitelist for allowed user inputs and reject non-compliant inputs
Path Traversal Vulnerability
Path traversal vulnerability, also known as directory traversal vulnerability, is another web security vulnerability that allows attackers to access files outside of the intended directory. An attacker can exploit this vulnerability to access sensitive files, such as configuration files, password files, and even source code files.
This vulnerability occurs when you create file paths using invalidated user input. This allows the attacker to navigate to directories and files using the ../
character sequences. The ../
character sequences refer to the parent directory on file systems.
Consider below revised version of our vulnerable PHP code.
$module = $_GET['module'];
include './' . $module;
By prefixing the module variable with ./
character sequences, we’re limiting file inclusion to the current directory only. So users cannot pass absolute file names like /etc/passwd
or URLs that will eliminate RFI. But the user can enter ../../../../../../../etc/passwd
as module parameter value and the final file path would resolve to /etc/passwd
. This will reveal the contents of the passwd file.
The Path traversal vulnerability can occur in any programming language and also in Windows operating systems.
Prevent Path Traversal Vulnerability
- Do not include or open files that are built using user-provided data
- If you must use inputs from users in file paths, use a strict whitelist for allowed user inputs and reject non-compliant inputs
- Use libraries to detect if the file you’re going to access is in the intended directory (e.g.
realpath()
in PHP and NodeJs)
File Upload Vulnerability
When it comes to uploading files, security is paramount. Unfortunately, there is a severe vulnerability called arbitrary file upload that can compromise your data. This vulnerability allows users to upload any type of file, including scripts like PHP, Python, or ASP code, which can execute any command on your server.
In addition to arbitrary file upload, insecure file upload functionality can also introduce other vulnerabilities like Denial of Service (DoS) attacks. For example, if you don’t set a limit on the file size that can be uploaded, an attacker could upload an excessively large file and potentially cause a DoS attack or consume excessive server resources.
Furthermore, insecure file uploads can allow attackers to override sensitive files using path traversal or upload malware to your server.
Prevent Insecure File Uploads
To prevent file upload vulnerabilities from happening, implement the following measures:
- Set a reasonable file size limit and validate that uploaded files are within that limit.
- Validate that uploaded files are of the expected file type and reject any files that are not.
- Use randomly generated file names for storing uploaded files. If you have to use user-provided filenames, use a white list filter for accepted file names and reject other file names.
- Use reputable anti-virus or malware detection software to scan uploaded files before they are processed or stored on your server.
- Make sure uploaded files do not have execution permission.
- Make sure only required users have access to the uploaded files.