File inclusion vulnerabilities, including Remote File Inclusion (RFI) and Local File Inclusion (LFI) are most commonly found in web applications running PHP scripts, but also frequently occur in JSP, ASP and other code. They allow an attacker to submit input to the application for execution without proper validation, usually by exploiting code that fails to securely parse “include” statements. As a result, the application builds a path to malicious executable code and subsequently loads and runs it based on an attacker-controlled variable (e.g., a cookie or request parameter).
LFI and RFI are serious information security vulnerabilities that can lead to code execution on the web server or on the client-side, Denial of Service (DoS) or defacement of a site, and/or exfiltration of sensitive data. The main difference between them is where the malicious file can reside: remotely or only on the local/current server. The latter is more common, while the former is easier to exploit if present.
Overall, file inclusion vulnerabilities are very common in web applications. Some have argued that they should be among the OWASP Top 10. In particular, file inclusion has historically been a leading vector for website defacement attacks.
What Not to Do
Figure 1 below shows a typical example of vulnerable PHP code.
In general, improper use of just a few PHP functions (include, include_once, require, require_once) are responsible for file inclusion flaws. In the code above, “include” takes a request parameter specifying the name of the file to be included at runtime. Since the code is not checking the input in any way, an attacker can specify any file parameter and it will be executed, whether remote or local: an IP address, port number and filename, for instance.
In the case of PHP scripts, since PHP 5.2 all you have to do to eliminate the risk of RFI attacks is not specifically allow remote file includes via specifying a URL rather than a local file path. This is disabled by default for a number of reasons. Figure 2 below shows what not to do:
This simple option has eliminated many RFI flaws, which is why it’s now often easier for hackers to get a file onto the local application server and then perpetrate LFI attacks. Obviously, if you’re configuring a new server or have an application in production that uses PHP, you want to make sure you’re running PHP 5.2 or newer and that the allow_url_include flag is set to OFF.
To eliminate the risk of LFI attacks, the recommended approach is to disallow or prevent user-submitted input from being passed to any filesystem or framework API in your application. If that isn’t possible, you need to sanitize all such inputs.
Figure 3 shows a sanitization approach that falls short. In line #3, the developer has chosen to force the extension .html to be appended to the user-supplied filename.
Hackers can bypass this easily if they already control the local server, simply by creating a file with that name. Attackers can also insert #, @, ? or other characters to force PHP to reinterpret the URL and effectively discard the would-be extension.
The Best Approach for File Inclusion Prevention
To safely parse user-supplied filenames it’s much better to maintain a whitelist of acceptable filenames and use a corresponding identifier (not the actual name) to access the file. Any request containing an invalid identifier can then simply be rejected. This is the approach that OWASP recommends.
For more information on mitigating file inclusion flaws in your application:
- Download our free OWASP ASVS Testing Guide
- OWASP guidance on testing for file inclusion vulnerabilities.
- OWASP Application Security Verification Standard control V16 concerns file verification requirements; V16.5 relates specifically to RFI flaws. ASVS V5 relates to verifying inputs and logging input validation failures.
- Mitre’s Common Weakness Enumeration (CWE) list references LFI/RFI as CWE-98.
To get whatever expert support you need to identify and prioritize critical risks and to verify that your application is secure, contact Pivot Point Security.