From 126e5fcf9311a4fd9dabf0dd41a670dc041ec7aa Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Fri, 16 Oct 2026 09:24:46 -0700 Subject: [PATCH] Fix RCE Vulnerability --- .../Api/ScriptExecutorController.php | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/ProcessMaker/Http/Controllers/Api/ScriptExecutorController.php b/ProcessMaker/Http/Controllers/Api/ScriptExecutorController.php index c499cd1e80..c68c4a1580 100644 --- a/ProcessMaker/Http/Controllers/Api/ScriptExecutorController.php +++ b/ProcessMaker/Http/Controllers/Api/ScriptExecutorController.php @@ -327,11 +327,41 @@ private function checkAuth($request) */ public function cancel(Request $request) { - $pidFile = $request->input('pidFile'); - $pid = file_get_contents($pidFile); - exec("kill -9 $pid"); + $this->checkAuth($request); + + $request->validate([ + 'pidFile' => 'required|string', + ]); + + $pid = $this->readBuildScriptExecutorPidFromFile($request->input('pidFile')); + exec(sprintf('kill -9 %d', $pid)); + + return ['status' => 'canceled', 'pid' => (string) $pid]; + } + + private function readBuildScriptExecutorPidFromFile(string $pidFile): int + { + if (!preg_match('#^/tmp/build_script_executor_[a-zA-Z0-9]+$#', $pidFile)) { + throw ValidationException::withMessages(['pidFile' => __('Invalid pid file.')]); + } + + $resolvedPidFile = realpath($pidFile); + $tmpDirectory = realpath('/tmp'); + if ( + $resolvedPidFile === false + || $tmpDirectory === false + || !str_starts_with($resolvedPidFile, $tmpDirectory . DIRECTORY_SEPARATOR) + || !is_readable($resolvedPidFile) + ) { + throw ValidationException::withMessages(['pidFile' => __('Invalid pid file.')]); + } + + $pid = trim((string) file_get_contents($resolvedPidFile)); + if ($pid === '' || !ctype_digit($pid) || (int) $pid <= 0) { + throw ValidationException::withMessages(['pidFile' => __('Invalid pid file.')]); + } - return ['status' => 'canceled', 'pid' => $pid]; + return (int) $pid; } /**