Normalized Safe Path
A PHP library for normalizing file paths and preventing directory traversal attacks.
Installation
Install via Composer:
composer require adachsoft/normalized-safe-path
Requirements
- PHP 7.4 or higher
- Composer
Usage
Basic Usage
<?php
use AdachSoft\NormalizedSafePath\SafePath;
use AdachSoft\NormalizedSafePath\SafePathHelper;
$safePath = new SafePath('/var/www/html');
$normalized = $safePath->normalize('uploads/../images/file.jpg');
$normalized = SafePathHelper::normalize('/var/www/html', 'uploads/../images/file.jpg');
Security Features
The library automatically prevents directory traversal attacks:
<?php
use AdachSoft\NormalizedSafePath\SafePath;
use AdachSoft\NormalizedSafePath\Exception\InvalidPathException;
$safePath = new SafePath('/var/www/html');
try {
$safePath->normalize('../../../etc/passwd');
} catch (InvalidPathException $e) {
echo "Path traversal detected!";
}
Path Normalization Features
- Cross-platform separators: Handles both
/ and \ as path separators
- Dot resolution: Removes
. and resolves .. appropriately
- Double slash normalization: Normalizes multiple consecutive slashes
- Empty path handling: Returns empty string for empty or dot-only paths
<?php
$safePath = new SafePath('/base');
$safePath->normalize('folder\\subfolder/file.txt');
$safePath->normalize('./folder/../other/./file.txt');
$safePath->normalize('folder//subfolder///file.txt');
API Reference
SafePath Class
Constructor
new SafePath(string $basePath)
- $basePath: The base directory path for validation
Methods
normalize(string $path): string
- $path: The path to normalize and validate
- Returns: Normalized path relative to base directory
- Throws:
InvalidPathException if path traversal is detected
SafePathHelper Class
Static Methods
SafePathHelper::normalize(string $basePath, string $path): string
- $basePath: The base directory path
- $path: The path to normalize and validate
- Returns: Normalized path
- Throws:
InvalidPathException if path traversal is detected
Exception Handling
The library throws AdachSoft\NormalizedSafePath\Exception\InvalidPathException when:
- A path attempts to traverse outside the base directory using
..
- The resolved path would escape the base directory
Examples
File Upload Security
<?php
use AdachSoft\NormalizedSafePath\SafePath;
$uploadDir = '/var/www/uploads';
$safePath = new SafePath($uploadDir);
$userFilename = $_POST['filename'] ?? '';
try {
$safeFilename = $safePath->normalize($userFilename);
$fullPath = $uploadDir . DIRECTORY_SEPARATOR . $safeFilename;
move_uploaded_file($_FILES['file']['tmp_name'], $fullPath);
} catch (InvalidPathException $e) {
http_response_code(400);
echo "Invalid file path provided";
}
Configuration File Loading
<?php
use AdachSoft\NormalizedSafePath\SafePathHelper;
$configDir = '/app/config';
$configFile = SafePathHelper::normalize($configDir, $_GET['config'] ?? 'default.json');
$configPath = $configDir . DIRECTORY_SEPARATOR . $configFile;
if (file_exists($configPath)) {
$config = json_decode(file_get_contents($configPath), true);
}
Testing
Run the test suite:
composer test
Run with coverage:
composer test-coverage
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
Author
Arkadiusz Adach