realpath()
Also Known As
realpath()
PHP canonical path
resolve symlinks
TL;DR
Resolves a path to its canonical absolute form, collapsing ../ sequences — used to prevent path traversal.
Explanation
realpath($path) resolves all symbolic links, /../ and /./ sequences, and redundant separators to produce the canonical absolute path. It returns false if the file doesn't exist. The standard path traversal guard is: $real = realpath($base . '/' . $userInput); if ($real === false || strpos($real, $base) !== 0) { deny; }. This ensures the resolved path starts with the intended base directory, regardless of what the user submitted.
Common Misconception
✗ realpath() is safe to use on any user-supplied path. realpath() resolves the canonical path including symlinks — it returns false for non-existent paths, which must be checked. Always verify the resolved path starts with the expected base directory before using it.
Why It Matters
realpath() resolves symlinks, . and .. components, and returns the canonical absolute path — it is the essential step before comparing user-supplied paths to allowed base directories.
Common Mistakes
- Checking path prefix before calling realpath() — traversal sequences pass the check but resolve differently.
- Not handling realpath() returning false for non-existent paths — the comparison silently fails.
- Using realpath() without checking that the result starts with the intended base directory.
- Trusting that realpath() sanitises the path for security without the subsequent base-directory check.
Code Examples
✗ Vulnerable
// Check before realpath — bypassable:
$path = '/var/www/uploads/' . $_GET['file'];
if (str_starts_with($path, '/var/www/uploads/')) {
readfile($path); // ../../etc/passwd passes the check!
}
// Correct:
$real = realpath('/var/www/uploads/' . $_GET['file']);
if ($real === false || !str_starts_with($real, '/var/www/uploads/')) die('Denied');
readfile($real);
✓ Fixed
// realpath() resolves ../, ./, symlinks to canonical absolute path
// Returns false if path doesn't exist
\$base = realpath('/var/www/uploads');
\$path = realpath(\$base . '/' . \$_GET['file']);
if (\$path === false) abort(404); // file doesn't exist
if (!str_starts_with(\$path, \$base . DIRECTORY_SEPARATOR)) abort(403); // path traversal
readfile(\$path);
// basename() strips directory components:
basename('../../../etc/passwd'); // 'passwd'
\$safe = '/var/www/uploads/' . basename(\$_GET['file']); // still need realpath() too
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
28
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Amazonbot 7
Perplexity 5
Ahrefs 4
Unknown AI 3
SEMrush 3
Google 2
Also referenced
How they use it
crawler 22
crawler_json 1
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟠 High
⚙ Fix effort: Low
⚡ Quick Fix
Always use realpath() to resolve the canonical absolute path before file operations on user-supplied paths — then verify the resolved path starts with your allowed base directory with str_starts_with()
📦 Applies To
PHP 5.0+
web
cli
🔗 Prerequisites
🔍 Detection Hints
File operations with user-supplied path without realpath() validation; path traversal ../ not checked; file existence checked by different path than used
Auto-detectable:
✓ Yes
semgrep
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Medium
✓ Auto-fixable
Fix: Low
Context: Function
CWE-22
CWE-73