Local file inclusion (LFI) remains a common web vulnerability because many applications dynamically load files based on user input, from templates and images to configuration files and modules. When that input is not properly validated, attackers can manipulate it to access unintended files on the web server.
The impact is often underestimated and waved off as “just a file read”. What starts as simple file access can quickly expose sensitive information such as credentials, API keys, and application logic. From there, attackers can escalate to access backend systems, pivot into cloud services, or chain with other weaknesses to get remote code execution.
A typical attack path is that an attacker reads a .env file or probes system files like /etc/passwd to understand your environment, extracts credentials, and uses that information to access databases or infrastructure. In modern environments, this can extend to environment variables or cloud or API tokens, which opens up the risk of a local file inclusion vulnerability escalating to a broader compromise.
Local file inclusion (LFI) is a web vulnerability where an application uses unsanitized and unvalidated user-controlled input to request and access files. Successful LFI may allow attackers to read arbitrary files on the server, resulting in information disclosure. In some cases, LFI can be chained with other weaknesses to execute malicious code. Note that unlike remote file inclusion (RFI), LFI only accesses files already present on the local system.
Here’s a high-level overview of how attackers might investigate and exploit local file inclusion vulnerabilities.
Many web applications dynamically load files based on parameters passed at runtime. Examples of using such behavior include page or template selection, file download or preview features, image or document display, or modular application components.
A typical vulnerable PHP script that loads a file based on a raw parameter value might look like this:
<?php
$file = $_GET['file'];
include($file);
?>If input is not restricted, attackers can supply arbitrary paths and manipulate them as described in the next step. Note that user-controlled input may come from many places besides the most obvious form fields, including query parameters, cookies, headers, or values such as the User-Agent header.
A safer approach might be to avoid the direct use of user input by relying on controlled mappings. This example defines an allowlist of page names and corresponding file paths, with only the page name controlled by the user:
<?php
$allowed = ['home' => 'home.php', 'about' => 'about.php'];
$page = $_GET['page'] ?? 'home';
if (array_key_exists($page, $allowed)) {
include(__DIR__ . '/pages/' . $allowed[$page]);
} else {
http_response_code(404);
}
?>While often associated with PHP, similar file access issues can occur in other languages, such as Python (send_file), Node.js (fs.readFile), or Java resource loading when user input is not properly validated.
Attackers exploit LFI vulnerabilities using path traversal (aka directory traversal) and related techniques. A simple payload included in a query parameter might look like:
?page=../../../../etc/passwd
Common techniques include:
../%2e%2e%2f)%00) in some older environments (PHP before 5.3.4)php://filter, php://input, or data://PHP wrappers in particular provide many possibilities. As an example of abusing php://filter, attackers might be able to use the Base64 encoding filter to read the source of a PHP file without executing it:
?file=php://filter/convert.base64-encode/resource=index.php
Other wrappers such as php://input and data:// are more dangerous because they allow attackers to supply file content (not just a path) directly in the request body or URL. This can turn an LFI vulnerability into remote code execution without resorting to techniques such as log poisoning or file uploads, since the application might directly include and execute attacker-controlled input as PHP code.
As with many other attacks, basic sanitization or blocklists might catch some exploits but are never sufficient protection on their own – attackers can bypass them using encoding, truncation tricks, or alternative path representations.
Once the path is controlled, attackers can try to retrieve environment-specific sensitive files such as:
/etc/passwd and other system files on Linux/var/www/var/log/apache2/access.log or error.log/proc/self/environ that may expose environment variables and secretsAt this stage, attackers gain insight into the application, its dependencies, and its execution environment.
Information disclosure is already dangerous enough, but attackers can escalate from just gathering data to using it for other attacks. Common escalation paths include:
Because LFI is restricted to files that are stored locally, more advanced attacks need some way to place an attacker-controlled file on the server. Two common techniques used against PHP applications are:
/var/log/apache2/access.logIn both cases, the attacker may be able to turn file read access into execution of PHP code on the server.
Though sometimes discounted as a low-risk weakness, local file inclusion can expose a wide variety of sensitive resources, including:
.env often contain database credentials, API keys, and cloud tokens.In LFI attacks, files are included from the local server. In RFI, the application loads files from an external source, which often enables direct code execution. However, LFI can sometimes be escalated to similar impact.
Path traversal allows attackers to access files not intended for user access by manipulating file paths. LFI refers to unsafe file inclusion or access within application logic. The two issues often overlap and share the same root cause – insufficient input validation and improper file handling. Definitions may vary, but in practice, LFI and path traversal often appear together.
LFI vulnerabilities can have serious business consequences, including:
For example, vulnerabilities in components such as TimThumb allowed attackers to read arbitrary files and execute code, which resulted in widespread website compromises. Similar issues have exposed configuration files and credentials, enabling attackers to pivot into databases and backend services.
There is no single fix that will prevent all LFI vectors. Apply the following best practices to minimize the risk of successful local file inclusion:
open_basedir in PHP environments. Isolation mechanisms such as containers or chroot environments can further limit impact if exploitation occurs.Confidently detecting a local file inclusion vulnerability requires testing how the application behaves at runtime. For known vulnerable software with reported CVEs, version checks using SCA tools can identify known issues. For custom applications, you need targeted testing of file-handling logic.
Static analysis using SAST tools is a valuable first step but is often insufficient on its own because it cannot reliably determine how user input is resolved into file paths during execution. As part of code review, developers should look for dangerous sinks where user input flows in without proper validation, for example include, require, or file_get_contents in PHP, and similar file access functions in other languages.
Automated vulnerability scanning at runtime is the most reliable way to identify accessible LFI vulnerabilities.
Dynamic application security testing (DAST) tools identify LFI by interacting with running applications. This includes crawling the application to discover inputs, injecting payloads that attempt to read local files, and analyzing responses for evidence of file access.
Advanced tools such as Invicti DAST can use proof-based scanning to confirm exploitability and provide evidence of impact. This reduces false positives and helps security teams focus on real, exploitable vulnerabilities rather than theoretical risks. Learn more about Invicti’s DAST-first approach that prioritizes what attackers can actually exploit, and request a demo to see how it can help you reduce real risk faster – for LFI and thousands of other vulnerabilities.
LFI involves including files from the local server, while RFI allows attackers to include files from external sources. RFI enables direct code execution more often, but some LFI can also be escalated to achieve similar results.
Yes. While LFI technically only allows file reading, attackers can combine it with techniques such as file uploads or log poisoning to execute malicious code on the server.
Security scanners detect LFI by sending crafted requests and analyzing responses for signs of file access. Advanced scanners validate exploitability using features such as Invicti’s proof-based scanning to help teams prioritize real, exploitable threats.
