Fix arbitrary file read via restore upload path (security)
stageRestoreUploadFromDirectAdminTemp() accepted the raw source_file_upload POST value as a literal filesystem path with only an is_file() check - no ownership or allowed-root validation, unlike the sibling queueRestoreFromFilePath(). isAllowedSqlFile() only checks the attacker-controlled display filename, never the real source path. Since the whole plugin runs as root, any authenticated DirectAdmin user could stage and restore-import any file readable by root on the server (e.g. other users' alt-mysql.conf credentials), leaking its contents via MySQL import error output or the resulting database. Remove the unsafe raw-path candidate entirely; only accept files whose basename matches one inside the already-safe, fixed set of known DirectAdmin/system temp directories.
This commit is contained in:
@@ -437,10 +437,12 @@ final class BackupQueueService
|
||||
throw new RuntimeException('Nie można odczytać przesłanego pliku backupu.');
|
||||
}
|
||||
|
||||
// Security: never trust $uploadReference as a literal path - it comes
|
||||
// straight from user-controlled POST data, and this whole plugin runs
|
||||
// as root. Only accept a file whose *basename* matches one of the
|
||||
// known DirectAdmin/system temp directories below, never an
|
||||
// arbitrary absolute path chosen by the caller.
|
||||
$sourceCandidates = [];
|
||||
if (str_starts_with($uploadReference, '/') && is_file($uploadReference)) {
|
||||
$sourceCandidates[] = $uploadReference;
|
||||
}
|
||||
$tmpDirs = [
|
||||
(string)(getenv('UPLOAD_TMP_DIR') ?: ''),
|
||||
(string)(getenv('DA_UPLOAD_TMP_DIR') ?: ''),
|
||||
|
||||
Reference in New Issue
Block a user