Path Traversal

Path Traversal and Remote File Inclusion

Whenever a filename, path or URL comes from the request, an attacker will point it somewhere you did not intend. Path traversal uses ../ to climb out of a directory; local file inclusion (LFI) turns that into code execution by include-ing an attacker-controlled file; server-side request forgery (SSRF) makes your server fetch a URL the attacker chose, often an internal address. All three come from concatenating untrusted input into a file or network path.

The fixes: a resolved-path prefix check, a page map, and an SSRF filterPHP
$real = realpath($base . $file);                    // traversal: resolve, then check the prefix
if ($real === false || !str_starts_with($real, $base)) exit("not found\n");
readfile($real);
// LFI: map the page name; never include a path built from input
include $viewDir . (['home' => 'home.php', 'about' => 'about.php'][$page] ?? 'home.php');
$ip = gethostbyname(parse_url($url, PHP_URL_HOST) ?? '');   // SSRF: resolve host, reject private
if (ip2long($ip) === false || $isPrivate) exit("blocked\n");

Sending each attack with curl 3,008 , then its mode=safe counterpart, gives (in order: traversal read, traversal blocked, LFI code execution, SSRF reaching an internal page, SSRF blocked):

Output of 185
root:x:0:0:root:/root:/bin/bash
not found
INCLUDED AS CODE: uid=33(www-data) gid=33(www-data) groups=33(www-data)
<!doctype html><meta charset="utf-8">
blocked: 192.168.0.5 is not a public address

The vulnerable readfile handed over /etc/passwd; the fix rejected the traversal because the resolved path fell outside its base. The vulnerable include executed a file an attacker had planted through an upload, proving LFI is a route to code execution. The SSRF endpoint fetched an internal-only page; the fix blocked a private address after resolving the host. allow_url_include is off by default, so remote inclusion over http:// no longer works; for outbound calls use cURL or Guzzle 23,452 with a host allow-list (Making HTTP Requests with cURL-Guzzle, PSR-7 and PSR-18), never file_get_contents() on a user URL.