RSTR-PTH-006 — PHP file API on request superglobal
Summary
file_get_contents, file_put_contents, fopen, readfile,
fpassthru, or file is called with a path derived directly from
$_GET, $_POST, $_REQUEST, or $_COOKIE. An attacker submits
../../etc/passwd and the application reads or writes outside the
intended directory.
Distinct from RSTR-PTH-005: that rule covers
the include / require family, which executes PHP. This one covers
generic file reads / writes, which expose or overwrite arbitrary
files but don't execute them.
Severity
High.
Languages
PHP.
What rastray flags
$content = file_get_contents($_GET['url']); // ← flagged
$fp = fopen($_POST['file'], 'r'); // ← flagged
readfile($_REQUEST['path']); // ← flagged
file_put_contents($_GET['name'], $data); // ← flagged
What rastray deliberately does not flag
- Calls with a constant path:
file_get_contents('/etc/myapp/config.json'). - Calls where the value flows through an intermediate variable (one-step taint scope, consistent across rastray).
How to fix it
Strip path components with basename, then resolve against a fixed
base directory and verify with realpath:
$base = realpath('/var/app/uploads');
$file = realpath($base . '/' . basename($_GET['name']));
if ($file === false || strpos($file, $base . DIRECTORY_SEPARATOR) !== 0) {
http_response_code(404);
exit;
}
return file_get_contents($file);
For URL fetches (where file_get_contents($_GET['url']) is actually
HTTP-based, not file-based), the bug is server-side request
forgery rather than path traversal. The fix is the same as
RSTR-SSRF-001: allow-list the host and
block private/loopback/metadata IPs before fetching.