---
title: Use Internal Data For File Paths
impact: CRITICAL
impactDescription: prevents Path Traversal and Local File Inclusion (LFI) attacks
tags: file-path, path-traversal, lfi, input-validation, security, php
---

## Use Internal Data For File Paths

Never construct file paths using raw user input. Simple strings like `../../etc/passwd` can be used by attackers to read sensitive configuration files or execute code on your server.

**Incorrect (user-controlled paths):**

```php
// Path traversal vulnerability
$page = $_GET['page'];
include("pages/" . $page . ".php"); 
// Attacker: ?page=../../../../etc/passwd

// File download vulnerability
$file = $_GET['file'];
readfile("/var/www/uploads/" . $file);
// Attacker: ?file=../config/database.php
```

**Correct (validated internal paths):**

```php
// 1. Using pathinfo/basename to strip directory separators
$file = $_GET['file'];
$safeName = basename($file); // strips any directory paths like ../

// 2. Validate against an allowlist (Safest)
$allowedFiles = ['report.pdf', 'invoice.pdf'];
if (!in_array($safeName, $allowedFiles)) {
    die("Unauthorized file access.");
}

// 3. Ensure the resolved path is within the intended directory
$baseDir = realpath('/var/www/uploads/');
$requestedPath = realpath($baseDir . '/' . $safeName);

if ($requestedPath === false || strpos($requestedPath, $baseDir) !== 0) {
    die("Invalid path traversal attempt.");
}

readfile($requestedPath);
```

**Security Checklist:**
1. **Always use [`basename()`](https://www.php.net/manual/en/function.basename.php)** to extract only the filename from user input.
2. **Use [`realpath()`](https://www.php.net/manual/en/function.realpath.php)** and verify that the resulting path still starts with your expected base directory.
3. **Prefer internal identifiers** (e.g., download by ID from a database) instead of exposing filenames in URLs.
4. **Disable `allow_url_include`** in `php.ini` to prevent Remote File Inclusion (RFI).

**Tools:** PHPInternal Security settings, SonarQube, Semgrep, OWASP ZAP
