Remote File Inclusion: 7 Smart Checks for RFI Flaws
Remote file inclusion is a web application vulnerability that appears when untrusted input can influence which file or remote resource the server includes. In a vulnerable setup, an attacker may be able to make the application fetch content from an external location and process it inside the application’s execution path. In this guide, I explain how RFI works, how it differs from local file inclusion, how I would check it safely in a controlled lab, and the practical fixes that remove the underlying trust problem.
The important detail is that remote file inclusion is not simply “a suspicious URL in a parameter.” The real weakness is allowing user-controlled data to decide what the application loads. Modern PHP installations make classic RFI less convenient because allow_url_include is disabled by default, but vulnerable code, legacy configurations, custom loaders, and equivalent patterns in other technologies still make the security lesson relevant.
| Issue | What the app loads | Main defensive question |
|---|---|---|
| Remote file inclusion | Content from a remote location | Can untrusted input control a remote include? |
| Local file inclusion | A file already on the server | Can input escape the intended local file set? |
| Safe design | A fixed, allowlisted resource | Does the server choose the file, not the user? |
Key Takeaways
- Remote file inclusion is a trust-boundary failure. User input should select an approved option, not supply a path or URL that the server blindly includes.
- RFI and LFI are related but different. RFI reaches a remote resource; LFI abuses access to files already available to the application.
- A safe lab does not need remote code execution. A harmless marker file is enough to prove that a remote resource was fetched or included.
- PHP configuration is only defense in depth. Keeping
allow_url_includedisabled helps, but the durable fix is removing user-controlled include paths from the application design. - Logs and outbound traffic matter. Unexpected remote hosts, strange schemes, or include-related errors can reveal attempted exploitation before a successful compromise is proven.
1. Understand What Remote File Inclusion Actually Is
At its simplest, remote file inclusion happens when an application uses untrusted data to choose a file or resource and permits that choice to point outside the intended application. The classic examples involve PHP functions such as include and require, but the broader design problem is technology-independent: the application lets the client influence a server-side resource decision that should have remained under server control.
The OWASP Web Security Testing Guide describes RFI as a file-inclusion weakness caused by user-supplied input that is not properly validated. Depending on the vulnerable implementation, the consequences can include server-side code execution, information disclosure, client-side effects, or denial of service. That range is why I avoid describing every RFI finding as instant “full server control.” The impact depends on what the application actually does with the included resource.
MITRE tracks the classic PHP form as CWE-98: improper control of a filename used by include, require, or similar statements. The useful lesson is not the identifier itself. It is the data flow: untrusted input travels from the request into a security-sensitive file-loading operation without a strong allowlist in between.
HackersGhost Note:
What I usually check first is the data flow, not the scary-looking URL. If the browser can supply a value that the server later treats as a filename or remote resource, I want to know exactly where that value is constrained. “It normally contains page names” is not a security control.

Why RFI can become code execution
Some include mechanisms do more than read a file as passive data. They parse or execute it as application code. In that situation, remote file inclusion can cross from “the server fetched something unexpected” into unauthorized code execution. That is a major escalation, but it is also exactly why a safe tutorial does not need to demonstrate a malicious payload. If a harmless marker proves that the application accepted an untrusted remote resource, the design flaw is already established.
2. Separate Remote File Inclusion From Local File Inclusion
Remote file inclusion and local file inclusion are often discussed together because both abuse dynamic file-loading logic. The difference is where the unwanted file comes from. RFI points the vulnerable application at a remote resource. LFI stays on the local filesystem and tries to reach a file that already exists on the server.
That distinction matters when you interpret evidence. If an application accepts ../../-style traversal and exposes a local configuration file, that is not automatically RFI. If it accepts an external URL and the server retrieves that remote resource through an include mechanism, you are much closer to a genuine remote file inclusion vulnerability.
There can be overlap in the same codebase. A poorly designed include parameter may allow a local path in one configuration and a remote URL in another. I still document the behavior separately because the fixes and the resulting impact can differ.
For another input-handling flaw, see SQL Injection Explained: 7 Essential Safe Lab Lessons
3. Find the Dangerous Inclusion Pattern Before Testing
The safest way to understand remote file inclusion is to start with source code you own. You are looking for a simple pattern: input from a request, form, cookie, header, database field, or API message reaches a file-loading operation without a strict mapping to approved resources.
A deliberately unsafe PHP example can be as small as this:
<?php
$page = $_GET['page'] ?? 'home.php';
include $page;
?>
The problem is not the variable name. It is that the client gets to choose the include target. If remote URL inclusion is enabled in the runtime and the input accepts a remote URL, the pattern can become remote file inclusion. Even when remote URLs are disabled, the same design can still create local file inclusion or path traversal problems.
A safer design turns the client input into a small identifier and maps that identifier to a server-controlled file:
<?php
$pages = [
'home' => __DIR__ . '/pages/home.php',
'help' => __DIR__ . '/pages/help.php',
];
$key = $_GET['page'] ?? 'home';
if (!array_key_exists($key, $pages)) {
http_response_code(404);
exit;
}
include $pages[$key];
?>
Now the user can choose home or help, but cannot supply an arbitrary path or URL. That is the design change I want to see. String filtering alone is fragile because there are many ways to represent paths, schemes, encodings, and wrapper-style resources. An explicit allowlist is easier to reason about.
HackersGhost Note:
One thing I learned while testing web apps in a lab is that source review can save a ridiculous amount of guessing. If I can see that a parameter feeds directly into an include statement, I already know where the trust boundary failed. The terminal does not receive bonus points for making the same discovery more dramatically.

4. Use a Harmless Remote File Inclusion Example in a Lab
A useful remote file inclusion example does not need a shell, malware, or a command-execution payload. In an isolated lab, you can prove the remote fetch with a text marker that contains no executable code. That keeps the test focused on the vulnerability instead of turning the exercise into a post-exploitation tutorial.
On my own setup, I would keep the vulnerable web application in a disposable VMware VM and use my Parrot OS VM for observation. The exact product is less important than the boundary: the target must be mine, intentionally vulnerable, and separated from normal systems. If the test app and marker server can reach the internet, I also verify that I am not accidentally creating a route into my everyday network.
Create a harmless file such as rfi-marker.txt containing one line:
RFI_LAB_MARKER_ONLY
Serve that file only inside your lab and use the vulnerable application’s own test parameter to reference it. The evidence you want is simply that the target server contacted the marker host or returned the marker where the include result appears. Stop there. If the marker is fetched through a user-controlled include path, the remote file inclusion condition has already been demonstrated without executing arbitrary code.
There are several acceptable outcomes. A secure application may reject the value immediately, map it to a fixed resource, or return a controlled error. A runtime may also refuse the remote include because configuration blocks it. That last result is useful defense in depth, but it does not magically make unsafe application logic good design.
What a safe RFI lab should record
- The exact application and version you own or are authorised to test.
- The parameter or code path that controls the include decision.
- The harmless marker resource and the lab-only host serving it.
- The HTTP response, application error, and any outbound request observed.
- The configuration change or code fix that removes the condition.
I would not use a public server as the marker host when a local VM or isolated container can do the job. Keeping the evidence inside the lab makes the test easier to repeat and easier to explain.
5. Inspect Requests With Burp Without Chasing Exploitation
Burp Suite is useful for remote file inclusion testing because it lets you see the exact request the browser sends and change one variable at a time. The goal is not to spray payloads across a target. In a controlled application, capture the known-good request, identify the parameter that selects the resource, and compare the server’s response when you provide a value that should be rejected.
What I care about is the decision boundary. Does the application accept only a logical identifier such as help? Does it accept a filesystem path? Does it accept a URL-looking value? Does the server attempt an outbound connection? Those observations tell you far more than a giant wordlist of random strings.
If you need the interception basics first, use my Burp Suite Proxy Tutorial: Intercept in 7 Easy Steps
What not to do during an RFI check
Do not turn a detection exercise into unnecessary exploitation. Once a harmless resource proves that untrusted input can control a remote include, you have enough evidence to fix the application. You do not need to upload a web shell, execute operating-system commands, establish persistence, or pivot to another service just to make the screenshot look more exciting.
This matters for reporting too. Write what you actually proved. “The application fetched a remote marker controlled by the test parameter” is precise. “The server is completely owned” is not justified unless you performed a separately authorised impact assessment that proved it.

6. Detect a Remote File Inclusion Attack From the Defensive Side
A remote file inclusion attack can leave traces even when it fails. Web server access logs may show unusual parameter values containing full URLs, unexpected schemes, encoded path characters, or repeated requests to an include-style endpoint. Application logs can show failed includes, wrapper errors, or attempts to load resources that are not part of the normal application.
Network visibility adds another layer. If a web server that normally talks only to a database suddenly makes outbound HTTP or DNS requests to an unfamiliar host, investigate why. Egress filtering can reduce the impact of remote file inclusion by blocking unnecessary outbound destinations, but I treat that as containment rather than the primary fix.
False positives are possible. A legitimate application may fetch remote templates, language packs, APIs, update metadata, or media. The question is whether the destination and resource are expected, whether the input is server-controlled, and whether the application validates the response before using it.
Useful defensive checks after an RFI alert
- Identify the affected route, parameter, authenticated user, source address, and timestamp.
- Check whether the server made a matching outbound request.
- Review application and runtime errors around the same time.
- Compare the requested resource with the application’s normal allowlist or configuration.
- Look for follow-on changes such as modified files, new processes, unexpected accounts, or altered scheduled tasks only if the evidence suggests code execution may have occurred.
If you find only a blocked attempt, say so. A log entry containing an RFI-looking URL proves an attempt or probe, not a successful compromise. I prefer a boring, accurate incident note over a dramatic conclusion that the evidence cannot support.

7. Fix Remote File Inclusion at the Design Level
The best remote file inclusion fix is architectural: do not pass user-controlled values directly into file, module, template, or include APIs. Give the user a small logical choice and map that choice to an application-controlled resource. OWASP recommends avoiding user-submitted input in filesystem and framework APIs where possible, or using a strict allowlist when a dynamic choice is genuinely required.
For PHP specifically, the official PHP filesystem configuration documentation states that allow_url_include controls whether URL-aware wrappers can be used with include, include_once, require, and require_once. It is disabled by default and has been deprecated for years. Keep it disabled unless you have an exceptional legacy reason and a documented security review.
That setting is not enough by itself. If the code still accepts arbitrary file paths, you may have converted a remote file inclusion problem into a local file inclusion problem rather than removing the unsafe design. Configuration should back up secure code, not replace it.
A practical RFI remediation checklist
- Remove arbitrary paths and URLs from request-controlled include logic.
- Use a fixed server-side map from short identifiers to known files or templates.
- Keep
allow_url_includedisabled on PHP systems and review other remote-resource features you do not need. - Run the web process with least privilege so a separate bug has less access to files and operating-system resources.
- Restrict unnecessary outbound traffic from web servers where operationally possible.
- Patch frameworks, plugins, and dependencies so known file-inclusion flaws do not remain reachable.
- Add regression tests that confirm unknown identifiers, paths, and URL-like values are rejected after the fix.
HackersGhost Note:
What matters to me here is whether the fix removes the attacker-controlled decision. Blocking one string, one hostname, or one URL scheme can make a demo stop working while leaving the design intact. I want the server to choose from known resources so there is nothing interesting left for the parameter to negotiate.
For a deliberately vulnerable practice environment, see Build a Safe OWASP Juice Shop Lab: 7 Proven Steps
Common Remote File Inclusion Mistakes I Would Avoid
Treating URL filtering as the whole fix
A blacklist of http:// strings may stop one obvious remote file inclusion example but still leave alternate schemes, encodings, local paths, or application-specific resource identifiers reachable. The safer pattern is positive selection: the server decides what can be loaded.
Assuming a 500 error proves exploitation
A server error tells you that something went wrong, not what security impact occurred. Correlate the response with application logs, source code, and outbound traffic before deciding whether the request reached a remote resource.
Testing production when a lab would answer the question
If you own the source code, recreate the vulnerable path in a disposable environment. A marker file in an isolated lab can confirm the same trust failure without exposing customer data, third-party infrastructure, or a live service to unnecessary risk.
Calling every file-inclusion issue RFI
If the application only reaches local files, document LFI or path traversal as appropriate. Precise naming helps developers reproduce the issue and helps defenders choose the right controls. Remote file inclusion should mean that the vulnerable behavior actually involves a remote resource.
Remote File Inclusion: What I Would Do First
If I inherited a web application and suspected remote file inclusion, my first move would be code review. I would search for dynamic include, template, module, and file-loading operations and trace their inputs backwards. Any path that begins with client-controlled data deserves attention.
Next, I would reproduce the behavior in a controlled environment with a harmless marker. If the marker proves a remote fetch, I would replace the dynamic path with a fixed allowlist, keep remote include features disabled, and add a regression test that rejects URL-like and unknown values. Then I would review logs for earlier attempts and, if evidence suggests successful code execution, widen the incident response accordingly.
That is the practical way I look at remote file inclusion: not as a magic URL trick, but as a server-side trust decision that should never have been handed to the client. Fix the decision, verify the fix, and record only the impact you can actually prove.

Remote File Inclusion FAQ
What is remote file inclusion?
Remote file inclusion is a vulnerability where untrusted input can influence a server-side include or file-loading operation so that the application retrieves a resource from a remote location. The risk depends on how that resource is processed, but unsafe remote inclusion can lead to serious impact including code execution.
What is the difference between RFI and LFI?
RFI involves a remote resource, while LFI involves a file already available on the local server or filesystem. Both can come from unsafe dynamic file-loading logic, but the evidence, configuration requirements, and possible impact are different.
Is remote file inclusion only a PHP problem?
No. The classic term is strongly associated with PHP include and require behavior, but the underlying weakness can appear anywhere an application lets untrusted input control a remote server-side resource or module load. The exact mechanics depend on the language and framework.
Does allow_url_include prevent remote file inclusion?
Keeping PHP’s allow_url_include disabled blocks the classic use of URL-aware wrappers with include and require functions and is valuable defense in depth. It does not repair application code that accepts arbitrary file paths, so the secure design should still use fixed server-controlled resources or an allowlist.
Can remote file inclusion lead to remote code execution?
It can. If the vulnerable include mechanism retrieves attacker-controlled content and interprets it as executable application code, RFI may become remote code execution. A safe lab does not need to demonstrate that step; a benign marker can prove the inclusion flaw without executing arbitrary commands.
How do you test remote file inclusion safely?
Use an application you own or have explicit permission to test, preferably in an isolated lab. Trace the include parameter, use a harmless remote marker, observe the request and response, and stop once the remote fetch is proven. Do not add code-execution or persistence steps when the vulnerability is already established.
What is the best fix for remote file inclusion?
The best fix is to remove user-controlled filenames and URLs from include logic. Map a small set of approved identifiers to fixed server-side files, keep remote include features disabled when they are not required, restrict unnecessary outbound traffic, and add tests that reject unknown resources.
Is a remote file inclusion attempt proof that my server was hacked?
No. A suspicious request proves that somebody sent a suspicious request. Check whether the application accepted the value, whether the server made a matching outbound connection, and whether any follow-on changes occurred before calling it a successful compromise.
Web Security & Credential Testing Cluster
- Remote File Inclusion: 7 Smart Checks for RFI Flaws 》》
- IDOR Vulnerability: 7 Sneaky Access Control Flaws 》》
- SQL Injection Explained: 7 Essential Safe Lab Lessons 》
- WordPress Hardening: 9 Real Fixes That Took Me From D to A+ 》
- Burp Suite Proxy Tutorial: Intercept in 7 Easy Steps 》
- 4 Password Hashing Algorithms Explained Clearly 》
- Dictionary Attack vs Brute Force: 7 Passwords Tested 》
- How to Use Hashcat: 7 Powerful Password Audit Steps 》
- John the Ripper Password Cracking: 7 Smart Lab Steps 》
- FFUF Tutorial for Beginners: 9 Practical Fuzzing Examples 》》
- Password Cracking: 7 Reasons Weak Passwords Fail Fast 》
- Gobuster Tutorial for Beginners: Find Hidden Directories Safely 》
- Hydra Kali Linux: 7 Practical Tests on Parrot OS Too 》》
- Nikto Web Server Scanner: 7 Useful Checks for Beginners 》
- How to Use Burp Suite Without 7 Common Beginner Mistakes 》
Some links in this article are affiliate links. If you use them, I may earn a small commission — at no extra cost to you. I only recommend tools I’ve actually tested inside my own cybersecurity lab. Read the full disclaimer.
In many cases, these links unlock better deals than you’ll find on your own.
No paid reviews. No sponsored opinions. Just real testing and real setups.
If you decide to use them, you’re not just getting a discount — you’re helping keep this lab running.

