← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Local File Inclusion (LFI)

Security CWE-98 OWASP A3:2021 CVSS 7.5 PHP 5.0+ Intermediate
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and psalm as the tools, both specialist SAST tools. The code_pattern identifies `include($_GET[` and similar patterns, which default linters won't catch but semgrep/psalm rules will. It won't be caught by the compiler or a standard linter, and it won't necessarily surface at runtime until exploited.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix states: 'Never pass user input to include/require; use a whitelist map of allowed template names to file paths.' This is a targeted fix — replacing dynamic include calls with a whitelist lookup — confined to include/require call sites, typically within one or a few files. It's more than a one-line patch but doesn't span the whole codebase.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The vulnerability applies to web and CLI PHP contexts but is scoped to include/require call sites that accept user input. Once fixed with a whitelist, the ongoing burden is low — future maintainers only need to update the whitelist when adding templates. It doesn't impose a persistent productivity tax across the entire codebase.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field states explicitly: 'LFI only lets attackers read files — it cannot lead to code execution.' This is a well-documented but seriously dangerous misconception. Developers familiar with file-read vulnerabilities may dismiss LFI as low-severity, not realising it escalates to RCE via log poisoning, session file inclusion, or PHP wrappers — behaviour that contradicts the intuitive 'local file inclusion = read only' mental model.

About DEBT scoring →

Also Known As

Local File Inclusion path inclusion file include vulnerability

TL;DR

A PHP include/require driven by user input that can load arbitrary local files, sometimes leading to code execution.

Explanation

LFI is a specific form of path traversal where the attacker causes the application to include a local file using PHP's include, require, include_once, or require_once. If the attacker can write a file to the server (e.g. via file upload), they can then include it and achieve remote code execution. Even without write access, LFI can expose /etc/passwd, application config files, and session data.

How It's Exploited

GET /index.php?page=../../../../etc/passwd%00
# %00 null byte terminates the .php extension (older PHP)
# Reads /etc/passwd contents

Common Misconception

LFI only lets attackers read files — it cannot lead to code execution. LFI can achieve RCE via log poisoning (injecting PHP into access logs then including them), PHP session file inclusion, or including uploaded files.

Why It Matters

Local file inclusion can expose source code, configuration files, and private keys — and combined with log poisoning, escalates to remote code execution.

Common Mistakes

  • Using user-supplied language or template parameters directly in include() without a strict whitelist.
  • Path traversal filtering that only strips ../ but misses URL-encoded or double-encoded variants.
  • PHP wrappers like php://filter and php://input being usable even when URL include is disabled.
  • Not using open_basedir to restrict which directories PHP can access at runtime.

Code Examples

✗ Vulnerable
$page = $_GET['page'];
include "pages/$page.php"; // LFI: ?page=../../../../etc/passwd%00
✓ Fixed
// Allowlist — only permit known page names
$allowed = ['home', 'about', 'contact', 'faq'];
$page    = $_GET['page'] ?? 'home';

if (!in_array($page, $allowed, true)) {
    $page = 'home';
}

include "pages/{$page}.php"; // only pages in the allowlist

Added 15 Mar 2026
Edited 12 Jun 2026
Views 79
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 3 pings W 4 pings T 6 pings F 1 ping S 6 pings S 5 pings M 2 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 25 Perplexity 9 Amazonbot 7 Ahrefs 7 Unknown AI 4 SEMrush 4 ChatGPT 3 Google 3 Majestic 1 Claude 1 Meta AI 1 Bing 1 PetalBot 1
crawler 61 crawler_json 3 pre-tracking 3
DEV INTEL Tools & Severity
🔴 Critical ⚙ Fix effort: Low
⚡ Quick Fix
Never pass user input to include/require; use a whitelist map of allowed template names to file paths
📦 Applies To
PHP 5.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
include($_GET[ or require($_GET[ or include($_POST[ or include($variable without allowlist
Auto-detectable: ✓ Yes semgrep psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✗ Manual fix Fix: High Context: Function Tests: Update
CWE-98 CWE-22


✓ schema.org compliant