You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(security): close 6 remaining command injection vectors in PBXCoreREST
Follow-up to 50dab8e which patched DownloadNewFirmwareAction and
ConvertAudioFileAction but missed these six shell-interpolation sinks.
1. Modules/StartDownloadAction: validate moduleUniqueID against
/^[A-Za-z0-9_\-]{1,128}$/, validate URL (http/https + filter_var),
validate md5 (32 hex), escapeshellarg on mwExecBg path argument.
This is the 1-to-1 twin of DownloadNewFirmwareAction (CVE-2025-52207).
2. Modules/UninstallModuleAction: validate moduleUniqueId with the same
whitelist; completely rewrite the kill-block that used a nested $()
subshell ("$kill -9 $($lsof ... | $awk '{print $2}' | $uniq)") —
now runs lsof via escapeshellarg, parses PIDs in PHP, kills each via
posix_kill(SIGKILL); escapeshellarg on "rm -rf $currentModuleDir".
3. Modules/ModuleInstallationBase: replace fragile single-quoted
'$settings_file' with escapeshellarg($settings_file) in mwExecBg.
4. System/UpgradeFromImageAction: new confineToUploadDir() helper with
realpath() prefix match rejects any imageFileLocation outside the
configured upload directory; whitelist /dev/[A-Za-z0-9/_-]+ on
bootPartition; escapeshellarg on mount/umount/gunzip/parted commands.
5. SysLogs/PrepareLogAction: escapeshellarg on $settings_file in
mwExecBg (defence in depth — $prefix is currently bool-derived).
6. Files/UploadFileAction: sanitize resumableIdentifier via whitelist
with strict equality rejection; cast resumableChunkNumber to int;
sanitize file extension from pathinfo() to [A-Za-z0-9]{0,16} —
closes both shell injection via crafted extension and a
FORBIDDEN_EXTENSIONS bypass where "hack.php;xyz" would parse as
extension "php;xyz", slip the blacklist, then land shell
metacharacters in downstream paths; apply the same extension
normalization inside validateFileType() so the blacklist operates on
the cleaned value; escapeshellarg on $chunks_dest_file and
$settings_file in mwExec/mwExecBg.
Verified on boffart.miko.ru (2026.1.233-dev) with PoCs against each
endpoint under a real admin JWT:
- Evil uniqid in modules:startDownload body → 400 "Invalid module id"
- Bad URL / bad md5 → 400 with specific message
- Clean module download → 200 DOWNLOAD_IN_PROGRESS
- Path traversal in system:upgrade (/etc/passwd) → 422
- Outside-uploadDir path → 422
- Evil resumableIdentifier (;touch, ../../, %27, %00) → rejected
- Evil extension (hack.php;xyz, hack.PhP) → 422 "Forbidden extension"
- Clean .wav upload → 200 MERGING
- No shell marker files created in any PoC
0 commit comments