← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Null Byte in File Paths (Legacy PHP)

Security PHP 3.0+ Advanced
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), semgrep rules for include/$_GET patterns will flag this, but it's silent at runtime on vulnerable PHP versions.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), quick_fix is sanitise with str_replace(chr(0), '', $input) plus realpath check, or upgrade PHP — small targeted change per include site.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3), affects file inclusion code paths in legacy web apps; applies_to is narrow (PHP 3.0-5.3 web contexts) so reach is bounded.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7), misconception is that modern PHP fixed it everywhere — extension append validation looks safe but null byte truncates the path, contradicting normal string handling intuition.

About DEBT scoring →

TL;DR

Null bytes (%00) in file paths truncated strings at the C level in PHP < 5.3.4 — PHP 5.3.4+ throws a warning, PHP 7 throws ValueError for NUL in paths.

Explanation

In PHP < 5.3.4, a null byte in a string terminated C-level string functions. Attackers exploited this: include $_GET['file'] . '.php'; with file=../../../../etc/passwd%00 stripped the .php extension, including /etc/passwd. Fixed in PHP 5.3.4 — file functions now reject strings containing NUL. PHP 7 throws ValueError for NUL in filenames. Legacy codebases on older PHP: validate with strpos($input, chr(0)) !== false. Modern PHP (7+): not exploitable but still worth sanitising for defence in depth.

Common Misconception

Null byte injection is fixed in all modern PHP — it is fixed in PHP 5.3.4+ and throws in PHP 7, but legacy codebases on older PHP remain vulnerable.

Why It Matters

Null byte injection in file paths bypassed extension validation and enabled arbitrary file inclusion on millions of PHP 4/5 sites.

Common Mistakes

  • Not upgrading from PHP 5.3.3 or earlier on legacy systems.
  • Not sanitising null bytes in input even on modern PHP (defence in depth).
  • Relying solely on extension append (.php) for security — null byte bypassed this.

Code Examples

✗ Vulnerable
// PHP < 5.3.4 — vulnerable:
$file = $_GET['file']; // 'shell.php%00'
include $file . '.php'; // Includes shell.php, ignores .php suffix
✓ Fixed
// Modern PHP (7+) throws automatically
// Defence in depth — sanitise anyway:
$file = str_replace(chr(0), '', $_GET['file'] ?? '');
$file = basename($file); // Remove path traversal
$path = realpath('/uploads/' . $file);
if ($path === false || !str_starts_with($path, '/uploads/')) {
    abort(400);
}

Added 23 Mar 2026
Views 42
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 2 pings M 0 pings T 1 ping W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 7 Google 5 Perplexity 4 ChatGPT 3 Ahrefs 3 Unknown AI 2 Claude 2 Scrapy 2 Bing 1 Meta AI 1 PetalBot 1 Sogou 1
crawler 25 crawler_json 4 pre-tracking 3
DEV INTEL Tools & Severity
🔴 Critical ⚙ Fix effort: Medium
⚡ Quick Fix
Upgrade PHP to 7+. Sanitise with str_replace(chr(0), '', $input). Always use realpath() + path prefix check for file operations.
📦 Applies To
PHP 3.0+ web
🔗 Prerequisites
🔍 Detection Hints
\$_GET.*\.php|include.*\$
Auto-detectable: ✓ Yes semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✗ Manual fix Fix: Medium Context: Function Tests: Update
CWE-158 CWE-22 CWE-626


✓ schema.org compliant