![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/private_html/includes/ |
<?php
/**
* File Security Utilities
* Prevents path traversal and unauthorized file access
*/
/**
* Validate and sanitize file path to prevent path traversal
*
* @param string $file_path The file path to validate
* @param array $allowed_directories Whitelist of allowed base directories
* @return string|false Returns normalized absolute path if valid, false otherwise
*/
function validateFilePath($file_path, $allowed_directories = null) {
if (empty($file_path)) {
return false;
}
// Default allowed directories
if ($allowed_directories === null) {
$allowed_directories = [
$_SERVER['DOCUMENT_ROOT'] . '/audio_files',
$_SERVER['DOCUMENT_ROOT'] . '/uploads',
];
}
// If it's already an absolute path
if (strpos($file_path, '/') === 0 || strpos($file_path, $_SERVER['DOCUMENT_ROOT']) === 0) {
// Ensure it's within DOCUMENT_ROOT
if (strpos($file_path, $_SERVER['DOCUMENT_ROOT']) !== 0) {
$file_path = $_SERVER['DOCUMENT_ROOT'] . $file_path;
}
} else {
// Relative path - make it absolute
$file_path = $_SERVER['DOCUMENT_ROOT'] . '/' . ltrim($file_path, '/');
}
// Normalize path (remove double slashes, resolve .. and .)
$file_path = str_replace('//', '/', $file_path);
$real_path = realpath($file_path);
// realpath() returns false if path doesn't exist or contains traversal
if ($real_path === false) {
return false;
}
// Ensure the resolved path is within DOCUMENT_ROOT
$doc_root = realpath($_SERVER['DOCUMENT_ROOT']);
if (strpos($real_path, $doc_root) !== 0) {
// Path is outside DOCUMENT_ROOT - security violation
error_log("SECURITY: Path traversal attempt detected: " . $file_path);
return false;
}
// Check if path is within allowed directories
$is_allowed = false;
foreach ($allowed_directories as $allowed_dir) {
$allowed_real = realpath($allowed_dir);
if ($allowed_real && strpos($real_path, $allowed_real) === 0) {
$is_allowed = true;
break;
}
}
if (!$is_allowed) {
error_log("SECURITY: File access outside allowed directories: " . $real_path);
return false;
}
// Verify file exists
if (!file_exists($real_path)) {
return false;
}
return $real_path;
}
/**
* Validate audio URL from database
* Ensures URL is either a valid external URL or a safe local path
*
* @param string $audio_url The audio URL to validate
* @return array Returns ['type' => 'local'|'external'|'invalid', 'path' => string|null, 'url' => string|null]
*/
function validateAudioUrl($audio_url) {
if (empty($audio_url)) {
return ['type' => 'invalid', 'path' => null, 'url' => null];
}
// Check if it's an external URL
if (strpos($audio_url, 'http://') === 0 || strpos($audio_url, 'https://') === 0) {
// Validate URL format
if (filter_var($audio_url, FILTER_VALIDATE_URL)) {
return ['type' => 'external', 'path' => null, 'url' => $audio_url];
} else {
return ['type' => 'invalid', 'path' => null, 'url' => null];
}
}
// It's a local path - validate it
$allowed_dirs = [
$_SERVER['DOCUMENT_ROOT'] . '/audio_files',
$_SERVER['DOCUMENT_ROOT'] . '/uploads',
];
$valid_path = validateFilePath($audio_url, $allowed_dirs);
if ($valid_path) {
return ['type' => 'local', 'path' => $valid_path, 'url' => null];
} else {
return ['type' => 'invalid', 'path' => null, 'url' => null];
}
}
/**
* Sanitize filename for download headers
*
* @param string $filename The filename to sanitize
* @return string Sanitized filename
*/
function sanitizeDownloadFilename($filename) {
// Remove or replace invalid characters
$filename = preg_replace('/[^a-zA-Z0-9\s\-_\.]/', '', $filename);
$filename = preg_replace('/\s+/', '_', $filename);
$filename = trim($filename, '._-');
// Limit length
if (strlen($filename) > 100) {
$filename = substr($filename, 0, 100);
}
return $filename;
}
?>