From c7fa1804e01acd40ab9a2e1bacf892161a4f4cc5 Mon Sep 17 00:00:00 2001 From: Christian Hackl Date: Fri, 2 Feb 2024 11:53:20 +0100 Subject: [PATCH 1/6] [TASK] remove unused code --- index.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/index.php b/index.php index b00080f..0f7f81e 100644 --- a/index.php +++ b/index.php @@ -1,12 +1,12 @@ getData(); $validate = $webhook->validateInit(); - + if($validate){ $webhook->handle(); } From 3d65b377d1d57988d35ebe2207ed9aea4333be90 Mon Sep 17 00:00:00 2001 From: Christian Hackl Date: Fri, 2 Feb 2024 12:34:32 +0100 Subject: [PATCH 2/6] [FEATURE] use bitbucket request header "X-Hub-Signature" - deprecate the simple payload validation --- lib/gitwebhook.php | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/gitwebhook.php b/lib/gitwebhook.php index 0ae3cbd..af71006 100644 --- a/lib/gitwebhook.php +++ b/lib/gitwebhook.php @@ -154,8 +154,49 @@ public function validateInit($lock=true){ } } - public function validate(){ - // Bitbucket Payload Validation (simple) + public function validate() { + // Bitbucket Payload Validation + if(isset(getallheaders()['X-Hub-Signature'])) { + $bitbucketSignature = getallheaders()['X-Hub-Signature']; + if(!empty($bitbucketSignature)) { + $requestContent = file_get_contents('php://input'); + if(!hash_equals('sha256=' . hash_hmac('sha256', $requestContent, $this->secret), $bitbucketSignature )) { + $this->notification("Error: Not compliant secrets","Please make sure the secret key is equal on both sides (Your Server & Bitbucket). \nBitbucket Secret is ".htmlspecialchars($_REQUEST["bitbucket_secret"])."\nJSON Config Secret is {$this->secret}"); + return false; + } + + $payload = json_decode($requestContent, true); + $event = @$_SERVER['HTTP_X_EVENT_KEY']; + $delivery = @$_SERVER['HTTP_X_REQUEST_UUID']; + $attemptNumber = @$_SERVER['HTTP_X_ATTEMPT_NUMBER']; + // X-Attempt-Number + // HTTP_X_ATTEMPT_NUMBER + + if(empty($payload)){ + $this->notification("Error: Payload is empty.","Something went really wrong about your payload (empty)."); + return false; + } + if(!isset($payload["repository"]["name"], $payload["push"]["changes"])){ + $this->notification("Error: Invalid Payload Data received.","Your payload data isn't valid.\nPayload Data:\n".print_r($payload,true)); + return false; + } + if(!isset($attemptNumber)){ + $this->notification("Error: Invalid Payload Data received (attemptNumber).","Your payload data isn't valid.\nPayload Data:\n".print_r($payload,true)); + return false; + } else if($attemptNumber>1){ + echo "The Git Execution is still in progress (this is the #{$attemptNumber} attempt), please wait.."; + return false; + } + + $this->data = $payload; + $this->event = $event; + $this->delivery = $delivery; + + return true; + } + } + + // @deprecated Bitbucket Payload Validation (simple - fallback) if(isset($_REQUEST['bitbucket_secret'])){ $payload = json_decode(file_get_contents('php://input'),true); $event = @$_SERVER['HTTP_X_EVENT_KEY']; From 23da9ca8a27e562e97f917e0f51212693f87b48c Mon Sep 17 00:00:00 2001 From: Christian Hackl Date: Fri, 2 Feb 2024 12:50:13 +0100 Subject: [PATCH 3/6] [TASK] added editorconfig --- .editorconfig | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5988100 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,96 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# TS-Files +[*.ts] +indent_style = space +indent_size = 4 + +# TYPOSCRIPT-Files +[*.typoscript] +indent_style = space +indent_size = 4 + +# YAML-Files +[*.yaml] +indent_style = space +indent_size = 2 + +# CSS-Files +[*.css] +indent_style = space +indent_size = 4 + +# HTML-Files +[*.html] +indent_style = space +indent_size = 4 + +# TMPL-Files +[*.tmpl] +indent_style = space +indent_size = 4 + +# LESS-Files +[*.less] +indent_style = space +indent_size = 4 + +# SASS-Files +[*.sass] +indent_style = space +indent_size = 4 + +# SCSS-Files +[*.scss] +indent_style = space +indent_size = 4 + +# JS-Files +[*.js] +indent_style = space +indent_size = 4 + +# PHP-Files +[*.php] +indent_style = space +indent_size = 4 + +# MD-Files +[*.md] +indent_style = space +indent_size = 4 + +# XLF-Files +[*.xlf] +indent_style = space +indent_size = 4 + +# JSON-Files +[*.json] +indent_style = space +indent_size = 4 + +# YML-Files +[*.yml] +indent_style = space +indent_size = 2 + +# SQL-Files +[*.sql] +indent_style = space +indent_size = 4 + +# package.json +[package.json, package-lock.json] +indent_style = space +indent_size = 2 From 42938e2182a0336627b64855b9e8ab627cfcd93d Mon Sep 17 00:00:00 2001 From: Christian Hackl Date: Fri, 2 Feb 2024 12:50:58 +0100 Subject: [PATCH 4/6] [TASK] maintaince - code format --- index.php | 49 +++--- lib/gitwebhook.php | 371 +++++++++++++++++++++++---------------------- 2 files changed, 212 insertions(+), 208 deletions(-) diff --git a/index.php b/index.php index 0f7f81e..ae6fa25 100644 --- a/index.php +++ b/index.php @@ -1,33 +1,34 @@ validateInit(); +$config = json_decode(file_get_contents($configFile),true); - if($validate){ +if(!is_readable($configFile)) { + $errMsg = "[ERROR]: The Gitwebhook Config File ({$configFile}) is not accessible / readable."; + if(ini_get('display_errors') != "1") echo "{$errMsg}"; + throw new Exception("{$errMsg}"); +} + +if(empty($config) || !is_array($config)) { + $errMsg = "[ERROR]: The Gitwebhook Config File ({$configFile}) is not a valid JSON File."; + if(ini_get('display_errors') != "1") echo "{$errMsg}"; + throw new Exception("{$errMsg}"); +} + +// Gitwebhook +$webhook = new Gitwebhook($config); +$validate = $webhook->validateInit(); + +if($validate) { $webhook->handle(); - } -?> +} diff --git a/lib/gitwebhook.php b/lib/gitwebhook.php index af71006..44c532b 100644 --- a/lib/gitwebhook.php +++ b/lib/gitwebhook.php @@ -11,72 +11,74 @@ class Gitwebhook private $linuxUser; private $debug; - public function __construct($config){ - $this->config = $this->getConfig($config); - $this->repository = $this->getConfigVar("git_repository"); - $this->branch = $this->getConfigVar("git_branch"); - $this->secret = $this->getConfigVar("git_secret"); - $this->deployDir = $this->getConfigVar("deployDir"); - $this->mail = $this->getConfigVar("mail"); - $this->mailSubject = $this->getConfigVar("mailSubject"); - $this->linuxUser = $this->getConfigVar("linux_user"); - $this->debug = $this->getConfigVar("debug") == "1" ? true : false; + public function __construct(array $config) { + $this->config = $this->getConfig($config); + $this->repository = $this->getConfigVar("git_repository"); + $this->branch = $this->getConfigVar("git_branch"); + $this->secret = $this->getConfigVar("git_secret"); + $this->deployDir = $this->getConfigVar("deployDir"); + $this->mail = $this->getConfigVar("mail"); + $this->mailSubject = $this->getConfigVar("mailSubject"); + $this->linuxUser = $this->getConfigVar("linux_user"); + $this->debug = $this->getConfigVar("debug") == "1" ? true : false; } // GETTER - public function getData(){ return $this->data; } - public function getDelivery(){ return $this->delivery; } - public function getEvent(){ return $this->event; } - public function getDeployDir(){ return $this->deployDir; } - public function getGitOutput(){ return $this->gitOutput; } - public function getRepository(){ return $this->repository; } - public function getSecret(){ return $this->secret; } - - protected function getConfigVar($name,$mode="text"){ - if(!isset($this->config[$name]) || empty($this->config[$name])) return ""; - if($mode == "text") return $this->config[$name]; - if($mode == "shell") return escapeshellarg($this->config[$name]); - return ""; + public function getData() { return $this->data; } + public function getDelivery() { return $this->delivery; } + public function getEvent() { return $this->event; } + public function getDeployDir(): string { return $this->deployDir; } + public function getGitOutput() { return $this->gitOutput; } + public function getRepository(): string { return $this->repository; } + public function getSecret(): string { return $this->secret; } + + protected function getConfigVar(string $name, string $mode="text"): string { + if(!isset($this->config[$name]) || empty($this->config[$name])) return ""; + if($mode == "text") return $this->config[$name]; + if($mode == "shell") return escapeshellarg($this->config[$name]); + + return ""; } - protected function getConfig($config){ - // Allocate the right gitwebhook config according to the right repo - $payloadData = json_decode(file_get_contents('php://input'),true); - $payloadDataRepoFullname = print_r($payloadData["repository"]["full_name"],true); - $configPick = false; - - foreach($config as $key => $conf){ - if(stristr($conf["git_repository"],$payloadDataRepoFullname)){ - $this->configName = str_replace(array("..","/"," "),array("","",""),$key); - $configPick = $conf; - break; + protected function getConfig($config) { + // Allocate the right gitwebhook config according to the right repo + $payloadData = json_decode(file_get_contents('php://input'), true); + $payloadDataRepoFullname = print_r($payloadData["repository"]["full_name"], true); + $configPick = false; + + foreach($config as $key => $conf) { + if(stristr($conf["git_repository"], $payloadDataRepoFullname)) { + $this->configName = str_replace(["..", "/", " "], ["", "", ""], $key); + $configPick = $conf; + break; + } + } + + if($configPick == false) { + $errMsg = "[ERROR]: Gitwebhook: Your repository ".htmlspecialchars($payloadDataRepoFullname,ENT_QUOTES,'utf-8')." didn't match any of the config repository entries."; + if(ini_get('display_errors') != "1") echo "{$errMsg}"; + + throw new Exception("{$errMsg}"); + } else { + return $configPick; } - } - - if($configPick == false){ - $errMsg = "[ERROR]: Gitwebhook: Your repository ".htmlspecialchars($payloadDataRepoFullname,ENT_QUOTES,'utf-8')." didn't match any of the config repository entries."; - if(ini_get('display_errors') != "1") echo "{$errMsg}"; - throw new Exception("{$errMsg}"); - } else { - return $configPick; - } } // SETTER, HELPER & VALIDATORS - public function notification($subject,$message,$mode="ERROR"){ - if($this->debug && $mode == "ERROR"){ - file_put_contents(__DIR__."/../logs/{$this->configName}_error_log_".date("Y-m-d-His").".log","{$subject}: {$message}\n\nConfig Data:\n".print_r($this->config,true)."\n"."Server Data:\n".print_r($_SERVER,true)); - } + public function notification(string $subject, string $message, string $mode="ERROR") { + if($this->debug && $mode == "ERROR") { + file_put_contents(__DIR__."/../logs/{$this->configName}_error_log_".date("Y-m-d-His").".log","{$subject}: {$message}\n\nConfig Data:\n".print_r($this->config,true)."\n"."Server Data:\n".print_r($_SERVER,true)); + } - if($this->mail != "false" && $this->mail != ""){ - $subjectWithInsertTag = str_replace('{{subject}}',$subject,$this->mailSubject); - $messagePrefix = "Repository: {$this->repository}\n"; + if($this->mail != "false" && $this->mail != "") { + $subjectWithInsertTag = str_replace('{{subject}}', $subject, $this->mailSubject); + $messagePrefix = "Repository: {$this->repository}\n"; - mail($this->mail,$subjectWithInsertTag,$messagePrefix.$message); - } + mail($this->mail, $subjectWithInsertTag, $messagePrefix.$message); + } } - public function handle(){ + public function handle() { $eol = PHP_EOL; // Set Identity Variables of the current Linux User and Group of the running script @@ -87,19 +89,19 @@ public function handle(){ $tmpBranch = escapeshellarg($this->branch); $tmpRepository = escapeshellarg($this->repository); - if(file_exists("{$this->deployDir}/.git")){ - $execCommand = "( cd {$tmpDeployDir} && git checkout {$tmpBranch} && git pull -f )"; - $tmpMailSubject = "Successful: Git pull executed"; + if(file_exists("{$this->deployDir}/.git")) { + $execCommand = "( cd {$tmpDeployDir} && git checkout {$tmpBranch} && git pull -f )"; + $tmpMailSubject = "Successful: Git pull executed"; } else { - $execCommand = "( cd {$tmpDeployDir} && git clone {$tmpRepository} . && git checkout {$tmpBranch} )"; - $tmpMailSubject = "Successful: Git clone executed"; + $execCommand = "( cd {$tmpDeployDir} && git clone {$tmpRepository} . && git checkout {$tmpBranch} )"; + $tmpMailSubject = "Successful: Git clone executed"; } // Setup execCommand as another Linux User if a Linux User is defined in the Config - if(!empty($this->linuxUser) && $currentUser != $this->linuxUser){ - $execCommand = "su -c '{$execCommand}' 2>&1 {$this->linuxUser}"; + if(!empty($this->linuxUser) && $currentUser != $this->linuxUser) { + $execCommand = "su -c '{$execCommand}' 2>&1 {$this->linuxUser}"; } else { - $execCommand = "{$execCommand} 2>&1"; + $execCommand = "{$execCommand} 2>&1"; } // Execute Git Pull / Clone Commands @@ -107,164 +109,165 @@ public function handle(){ // Generate Git Report $gitReport = $this->gitOutput; - if(is_array($this->gitOutput)){ + if(is_array($this->gitOutput)) { $gitReport = ""; - foreach($this->gitOutput as $oCnt => $oVal){ + foreach($this->gitOutput as $oCnt => $oVal) { $gitReport .= $oVal."\n"; } } // Send Notification about the Git Deployment (Git Report) - $this->notification($tmpMailSubject,"gitCommand:{$eol}{$execCommand}{$eol}{$eol}gitOutput:{$eol}{$gitReport}{$eol}Server Output:{$eol}".print_r($_SERVER,true),"TEXT"); + $this->notification($tmpMailSubject, "gitCommand:{$eol}{$execCommand}{$eol}{$eol}gitOutput:{$eol}{$gitReport}{$eol}Server Output:{$eol}".print_r($_SERVER, true), "TEXT"); return true; } - public function validateInit($lock=true){ - $validate = $this->validate(); + public function validateInit(bool $lock=true) { + $validate = $this->validate(); - // Lock Validation (Security) - if($lock){ - $lockFile = __DIR__."/../tmp/lock_gitwebhook"; - $lockFileContent = file_exists($lockFile) ? file_get_contents($lockFile) : "0"; - $lockNum = intval($lockFileContent); + // Lock Validation (Security) + if($lock) { + $lockFile = __DIR__."/../tmp/lock_gitwebhook"; + $lockFileContent = file_exists($lockFile) ? file_get_contents($lockFile) : "0"; + $lockNum = intval($lockFileContent); - // Reset Lock after 15 Minutes - if(file_exists($lockFile) && time() - filemtime($lockFile) > 900){ - file_put_contents($lockFile, "0", LOCK_EX); - $lockNum = 0; - } + // Reset Lock after 15 Minutes + if(file_exists($lockFile) && time() - filemtime($lockFile) > 900) { + file_put_contents($lockFile, "0", LOCK_EX); + $lockNum = 0; + } - // Set Lockdown if lockNum (lock attempts) is 10 or higher (for 15 Minutes) and set validate false - if($lockNum >= 10){ - $this->notification("Error: Too many errors / wrong attempts in a short time","Gitwebhook has reached too many errors / wrong attempts in a short time. This can be caused by a misconfiguration of the gitwebhook, access rights on your server, or even a suspicious process might be running. Please check your error emails or your error logs. The lock will be suspended after 15 Minutes and you can try again."); - return false; + // Set Lockdown if lockNum (lock attempts) is 10 or higher (for 15 Minutes) and set validate false + if($lockNum >= 10) { + $this->notification("Error: Too many errors / wrong attempts in a short time","Gitwebhook has reached too many errors / wrong attempts in a short time. This can be caused by a misconfiguration of the gitwebhook, access rights on your server, or even a suspicious process might be running. Please check your error emails or your error logs. The lock will be suspended after 15 Minutes and you can try again."); + return false; + } } - } - // Regular Validation - if($validate){ - return true; - } else { - if($lock){ - // Write new Lock with Lock Number - file_put_contents($lockFile, print_r(($lockNum+1),true), LOCK_EX); + // Regular Validation + if($validate) { + return true; + } else { + if($lock){ + // Write new Lock with Lock Number + file_put_contents($lockFile, print_r(($lockNum+1),true), LOCK_EX); + } + return false; } - return false; - } } - public function validate() { - // Bitbucket Payload Validation - if(isset(getallheaders()['X-Hub-Signature'])) { - $bitbucketSignature = getallheaders()['X-Hub-Signature']; - if(!empty($bitbucketSignature)) { - $requestContent = file_get_contents('php://input'); - if(!hash_equals('sha256=' . hash_hmac('sha256', $requestContent, $this->secret), $bitbucketSignature )) { - $this->notification("Error: Not compliant secrets","Please make sure the secret key is equal on both sides (Your Server & Bitbucket). \nBitbucket Secret is ".htmlspecialchars($_REQUEST["bitbucket_secret"])."\nJSON Config Secret is {$this->secret}"); - return false; - } - - $payload = json_decode($requestContent, true); - $event = @$_SERVER['HTTP_X_EVENT_KEY']; - $delivery = @$_SERVER['HTTP_X_REQUEST_UUID']; - $attemptNumber = @$_SERVER['HTTP_X_ATTEMPT_NUMBER']; - // X-Attempt-Number - // HTTP_X_ATTEMPT_NUMBER + public function validate(): bool { + // Bitbucket Payload Validation + if(isset(getallheaders()['X-Hub-Signature'])) { + $bitbucketSignature = getallheaders()['X-Hub-Signature']; + if(!empty($bitbucketSignature)) { + $requestContent = file_get_contents('php://input'); + if(!hash_equals('sha256=' . hash_hmac('sha256', $requestContent, $this->secret), $bitbucketSignature)) { + $this->notification("Error: Not compliant secrets", "Please make sure the secret key is equal on both sides (Your Server & Bitbucket)"); + return false; + } + + $payload = json_decode($requestContent, true); + $event = @$_SERVER['HTTP_X_EVENT_KEY']; + $delivery = @$_SERVER['HTTP_X_REQUEST_UUID']; + $attemptNumber = @$_SERVER['HTTP_X_ATTEMPT_NUMBER']; + // X-Attempt-Number + // HTTP_X_ATTEMPT_NUMBER + + if(empty($payload)) { + $this->notification("Error: Payload is empty.","Something went really wrong about your payload (empty)."); + return false; + } + if(!isset($payload["repository"]["name"], $payload["push"]["changes"])) { + $this->notification("Error: Invalid Payload Data received.","Your payload data isn't valid.\nPayload Data:\n".print_r($payload, true)); + return false; + } + if(!isset($attemptNumber)) { + $this->notification("Error: Invalid Payload Data received (attemptNumber).","Your payload data isn't valid.\nPayload Data:\n".print_r($payload, true)); + return false; + } else if($attemptNumber > 1) { + echo "The Git Execution is still in progress (this is the #{$attemptNumber} attempt), please wait.."; + return false; + } + + $this->data = $payload; + $this->event = $event; + $this->delivery = $delivery; + + return true; + } + } - if(empty($payload)){ - $this->notification("Error: Payload is empty.","Something went really wrong about your payload (empty)."); + // @deprecated Bitbucket Payload Validation (simple - fallback) + if(isset($_REQUEST['bitbucket_secret'])) { + $payload = json_decode(file_get_contents('php://input'), true); + $event = @$_SERVER['HTTP_X_EVENT_KEY']; + $delivery = @$_SERVER['HTTP_X_REQUEST_UUID']; + $attemptNumber = @$_SERVER['HTTP_X_ATTEMPT_NUMBER']; + // X-Attempt-Number + // HTTP_X_ATTEMPT_NUMBER + + if($_REQUEST["bitbucket_secret"] != $this->secret) { + $this->notification("Error: Not compliant secrets", "Please make sure the secret key is equal on both sides (Your Server & Bitbucket). \nBitbucket Secret is ".htmlspecialchars($_REQUEST["bitbucket_secret"])."\nJSON Config Secret is {$this->secret}"); + return false; + } + if(empty($payload)) { + $this->notification("Error: Payload is empty.", "Something went really wrong about your payload (empty)."); return false; - } - if(!isset($payload["repository"]["name"], $payload["push"]["changes"])){ - $this->notification("Error: Invalid Payload Data received.","Your payload data isn't valid.\nPayload Data:\n".print_r($payload,true)); + } + if(!isset($payload["repository"]["name"], $payload["push"]["changes"])) { + $this->notification("Error: Invalid Payload Data received.","Your payload data isn't valid.\nPayload Data:\n".print_r($payload, true)); return false; - } - if(!isset($attemptNumber)){ - $this->notification("Error: Invalid Payload Data received (attemptNumber).","Your payload data isn't valid.\nPayload Data:\n".print_r($payload,true)); + } + if(!isset($attemptNumber)) { + $this->notification("Error: Invalid Payload Data received (attemptNumber).","Your payload data isn't valid.\nPayload Data:\n".print_r($payload, true)); return false; - } else if($attemptNumber>1){ + } else if($attemptNumber > 1) { echo "The Git Execution is still in progress (this is the #{$attemptNumber} attempt), please wait.."; return false; - } - - $this->data = $payload; - $this->event = $event; - $this->delivery = $delivery; - - return true; - } - } - - // @deprecated Bitbucket Payload Validation (simple - fallback) - if(isset($_REQUEST['bitbucket_secret'])){ - $payload = json_decode(file_get_contents('php://input'),true); - $event = @$_SERVER['HTTP_X_EVENT_KEY']; - $delivery = @$_SERVER['HTTP_X_REQUEST_UUID']; - $attemptNumber = @$_SERVER['HTTP_X_ATTEMPT_NUMBER']; - // X-Attempt-Number - // HTTP_X_ATTEMPT_NUMBER - - if($_REQUEST["bitbucket_secret"] != $this->secret){ - $this->notification("Error: Not compliant secrets","Please make sure the secret key is equal on both sides (Your Server & Bitbucket). \nBitbucket Secret is ".htmlspecialchars($_REQUEST["bitbucket_secret"])."\nJSON Config Secret is {$this->secret}"); - return false; - } - if(empty($payload)){ - $this->notification("Error: Payload is empty.","Something went really wrong about your payload (empty)."); - return false; + } + + $this->data = $payload; + $this->event = $event; + $this->delivery = $delivery; + + return true; } - if(!isset($payload["repository"]["name"], $payload["push"]["changes"])){ - $this->notification("Error: Invalid Payload Data received.","Your payload data isn't valid.\nPayload Data:\n".print_r($payload,true)); - return false; + + // Github Payload Validation + $signature = @$_SERVER['HTTP_X_HUB_SIGNATURE']; + $event = @$_SERVER['HTTP_X_GITHUB_EVENT']; + $delivery = @$_SERVER['HTTP_X_GITHUB_DELIVERY']; + $payload = file_get_contents('php://input'); + $payloadData = json_decode($payload,true); + + if (!isset($signature, $event, $delivery)) { + $this->notification("Error: Signature, Event or Delivery (Header) is not set.","Server Output:\n".print_r($_SERVER, true)."\n\nWebhook Data:\n".print_r($payloadData, true)); + return false; } - if(!isset($attemptNumber)){ - $this->notification("Error: Invalid Payload Data received (attemptNumber).","Your payload data isn't valid.\nPayload Data:\n".print_r($payload,true)); - return false; - } else if($attemptNumber>1){ - echo "The Git Execution is still in progress (this is the #{$attemptNumber} attempt), please wait.."; - return false; + + if (!$this->validateSignature($signature, $payload)) { + $this->notification("Error: Secret (or Payload) Validation Failed","Server Output:\n".print_r($_SERVER, true)."\n\nWebhook Data:\n".print_r($payloadData, true)); + return false; } - $this->data = $payload; + $this->data = $payloadData; $this->event = $event; $this->delivery = $delivery; return true; - } - - // Github Payload Validation - $signature = @$_SERVER['HTTP_X_HUB_SIGNATURE']; - $event = @$_SERVER['HTTP_X_GITHUB_EVENT']; - $delivery = @$_SERVER['HTTP_X_GITHUB_DELIVERY']; - $payload = file_get_contents('php://input'); - $payloadData = json_decode($payload,true); - - if (!isset($signature, $event, $delivery)) { - $this->notification("Error: Signature, Event or Delivery (Header) is not set.","Server Output:\n".print_r($_SERVER,true)."\n\nWebhook Data:\n".print_r($payloadData,true)); - return false; - } - - if (!$this->validateSignature($signature, $payload)) { - $this->notification("Error: Secret (or Payload) Validation Failed","Server Output:\n".print_r($_SERVER,true)."\n\nWebhook Data:\n".print_r($payloadData,true)); - return false; - } - - $this->data = $payloadData; - $this->event = $event; - $this->delivery = $delivery; - return true; } - protected function validateSignature($gitHubSignatureHeader, $payload){ - // Github Payload Validation - list ($algo, $gitHubSignature) = explode("=", $gitHubSignatureHeader); + protected function validateSignature($gitHubSignatureHeader, $payload) { + // Github Payload Validation + list($algo, $gitHubSignature) = explode("=", $gitHubSignatureHeader); - if ($algo !== 'sha1') { - // see https://developer.github.com/webhooks/securing/ - return false; - } + if ($algo !== 'sha1') { + // see https://developer.github.com/webhooks/securing/ + return false; + } - $payloadHash = hash_hmac($algo, $payload, $this->secret); - return ($payloadHash === $gitHubSignature); + $payloadHash = hash_hmac($algo, $payload, $this->secret); + return ($payloadHash === $gitHubSignature); } } From d1786878124ea2df157332fdef096b5b9589876a Mon Sep 17 00:00:00 2001 From: Christian Hackl Date: Fri, 2 Feb 2024 12:55:45 +0100 Subject: [PATCH 5/6] [TASK] edit the readme for usage bitbucket webhook with the "secret" field --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e308312..814d7e4 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ Use the following steps to set up a new gitwebhook on your github (or bitbucket) 1. Go to your Repository and click on "Settings", then click on "Webhooks" 2. Click on "Add webhook" -3. Type in the path where you want to install your gitwebhook: https://\/gitwebhook/index.php?bitbucket_secret=\ (or as subdomain, etc.) - - (replace \ with a Secret of your choice) +3. Type in the name of the webhook (your own custom name) in the field "Title" +4. Type in the path where you want to install your gitwebhook (field "URL"): https://\/gitwebhook/index.php (or as subdomain, etc.) +5. Add your \ in the "secret" field (replace \ with a Secret of your choice) ### Setup Gitwebhook (Second Step): From f6af5b8952f7a28bd7b61ec867fa666aa93dfe3b Mon Sep 17 00:00:00 2001 From: Christian Hackl Date: Wed, 19 Jun 2024 15:19:44 +0200 Subject: [PATCH 6/6] [TASK] change readme git clone url Thx to iocron... --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 814d7e4..68b19eb 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Use the following steps to set up a new gitwebhook on your github (or bitbucket) 2. Clone the gitwebhook ``` - git clone https://github.com/iocron/gitwebhook.git && cd gitwebhook + git clone https://github.com/Teisi/gitwebhook.git && cd gitwebhook ``` 3. Copy configuration file and htaccess so you can use them: