mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 18:52:49 +00:00
fix(webhooks): scope manual webhook lockouts to repository and branch
Failed manual webhook deliveries were counted per provider and source IP. On Coolify Cloud many customers share the Git provider IP, so one repository with a wrong secret locked out valid deliveries of all other repositories for 60 seconds. The failure key now also contains the repository and branch. Guessing the secret of one application stays limited to 30 tries per minute, and a lockout rejects all deliveries in that scope, also correct ones. A GitLab request without a token no longer counts as a failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1e207292b6
commit
bbee57a81a
8 files changed
+224
-94
No files matched your search
@@ -25,10 +25,6 @@ class Github extends Controller
|
||||
|
||||
public function manual(Request $request)
|
||||
{
|
||||
if ($this->hasTooManyManualWebhookFailures($request, 'github')) {
|
||||
return $this->tooManyManualWebhookFailuresResponse($request, 'github');
|
||||
}
|
||||
|
||||
try {
|
||||
$return_payloads = collect([]);
|
||||
$x_github_delivery = request()->header('X-GitHub-Delivery');
|
||||
@@ -79,21 +75,22 @@ class Github extends Controller
|
||||
if ($full_name === null) {
|
||||
return response('Nothing to do. Invalid repository.');
|
||||
}
|
||||
$applications = Application::query();
|
||||
if ($x_github_event === 'push') {
|
||||
$applications = $this->manualWebhookApplications($applications->where('git_branch', $branch), $full_name);
|
||||
if ($applications->isEmpty()) {
|
||||
return $this->unauthenticatedManualWebhookResponse($request, 'github');
|
||||
}
|
||||
$matched_branch = match (true) {
|
||||
$x_github_event === 'push' => $branch,
|
||||
$action === 'closed' => null,
|
||||
default => $base_branch,
|
||||
};
|
||||
$failure_key = $this->manualWebhookFailureRateLimitKey($request, 'github', $full_name, $matched_branch);
|
||||
if ($this->hasTooManyManualWebhookFailures($failure_key)) {
|
||||
return $this->tooManyManualWebhookFailuresResponse($failure_key);
|
||||
}
|
||||
if ($x_github_event === 'pull_request') {
|
||||
if ($action !== 'closed') {
|
||||
$applications->where('git_branch', $base_branch);
|
||||
}
|
||||
$applications = $this->manualWebhookApplications($applications, $full_name);
|
||||
if ($applications->isEmpty()) {
|
||||
return $this->unauthenticatedManualWebhookResponse($request, 'github');
|
||||
}
|
||||
$applications = Application::query();
|
||||
if ($x_github_event === 'push' || $action !== 'closed') {
|
||||
$applications->where('git_branch', $matched_branch);
|
||||
}
|
||||
$applications = $this->manualWebhookApplications($applications, $full_name);
|
||||
if ($applications->isEmpty()) {
|
||||
return $this->unauthenticatedManualWebhookResponse($failure_key);
|
||||
}
|
||||
$applicationsByServer = $applications->groupBy(function ($app) {
|
||||
return $app->destination->server_id;
|
||||
@@ -243,7 +240,7 @@ class Github extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return $this->manualWebhookResponse($return_payloads, $request, 'github');
|
||||
return $this->manualWebhookResponse($return_payloads, $failure_key);
|
||||
} catch (Exception $e) {
|
||||
return handleError($e);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user