mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix: enforce webhook lockouts and stop cancelled runner provisioning
- Manual webhooks (GitHub, GitLab, Gitea, Bitbucket) now reject all deliveries for a locked-out scope before reading secrets or verifying signatures, including correctly signed ones, until the window expires. - ProvisionGithubRunnerJob checks whether the execution has already finished before and after each provisioning step, and only sets ready_at or Failed while it is still occupying/provisioning. A runner that is cancelled, timed out or completed mid-provisioning is no longer started, retried or overwritten. - VolumeCloneJob creates bind-volume clones as plain local volumes without the source driver options, so the clone never mounts the source host directory. - Image pulls for additional servers no longer ignore docker pull errors. - Add tests for each change.
This commit is contained in:
@@ -82,6 +82,10 @@ class Bitbucket extends Controller
|
||||
]);
|
||||
}
|
||||
$failure_key = $this->manualWebhookFailureRateLimitKey($request, 'bitbucket', $full_name, $branch);
|
||||
if ($this->hasTooManyManualWebhookFailures($failure_key)) {
|
||||
return $this->tooManyManualWebhookFailuresResponse($failure_key);
|
||||
}
|
||||
|
||||
// A redelivery of the same signed payload is one guess.
|
||||
$failure_attempt = $this->manualWebhookSignedPayloadAttempt($request, $x_bitbucket_token);
|
||||
$applications = $this->manualWebhookApplications(Application::query()->where('git_branch', $branch), $full_name);
|
||||
|
||||
@@ -18,9 +18,9 @@ use Illuminate\Support\Facades\RateLimiter;
|
||||
* IPs; one misconfigured repository (wrong secret, deleted application,
|
||||
* untracked branch) therefore cannot lock out deliveries for other repositories.
|
||||
*
|
||||
* The lockout applies only to deliveries that fail authentication. A delivery
|
||||
* with a valid secret for a matched application is always processed, so failed
|
||||
* attempts from anyone sharing the scope cannot block real deliveries.
|
||||
* After the failure limit is reached, the scope rejects all deliveries before
|
||||
* reading application secrets or verifying signatures. Correctly signed
|
||||
* deliveries in that scope must wait until the failure window expires.
|
||||
*
|
||||
* In one failure window, only distinct failed attempts are counted. An attempt
|
||||
* is identified by what the secret check depends on: the GitLab token, or the
|
||||
|
||||
@@ -74,6 +74,10 @@ class Gitea extends Controller
|
||||
}
|
||||
$matched_branch = $x_gitea_event === 'pull_request' ? $base_branch : $branch;
|
||||
$failure_key = $this->manualWebhookFailureRateLimitKey($request, 'gitea', $full_name, $matched_branch);
|
||||
if ($this->hasTooManyManualWebhookFailures($failure_key)) {
|
||||
return $this->tooManyManualWebhookFailuresResponse($failure_key);
|
||||
}
|
||||
|
||||
// A redelivery of the same signed payload is one guess.
|
||||
$failure_attempt = $this->manualWebhookSignedPayloadAttempt($request, $x_hub_signature_256);
|
||||
$applications = Application::query();
|
||||
|
||||
@@ -95,6 +95,10 @@ class Github extends Controller
|
||||
default => $base_branch,
|
||||
};
|
||||
$failure_key = $this->manualWebhookFailureRateLimitKey($request, 'github', $full_name, $matched_branch);
|
||||
if ($this->hasTooManyManualWebhookFailures($failure_key)) {
|
||||
return $this->tooManyManualWebhookFailuresResponse($failure_key);
|
||||
}
|
||||
|
||||
// A redelivery of the same signed payload is one guess.
|
||||
$failure_attempt = $this->manualWebhookSignedPayloadAttempt($request, $x_hub_signature_256);
|
||||
$applications = Application::query();
|
||||
|
||||
@@ -430,6 +430,10 @@ class Gitlab extends Controller
|
||||
}
|
||||
$matched_branch = $x_gitlab_event === 'merge_request' ? $base_branch : $branch;
|
||||
$failure_key = $this->manualWebhookFailureRateLimitKey($request, 'gitlab', $full_name, $matched_branch);
|
||||
if ($this->hasTooManyManualWebhookFailures($failure_key)) {
|
||||
return $this->tooManyManualWebhookFailuresResponse($failure_key);
|
||||
}
|
||||
|
||||
// GitLab sends a static token. A repeated wrong token is one guess.
|
||||
$failure_attempt = $this->manualWebhookTokenAttempt($x_gitlab_token);
|
||||
$applications = Application::query();
|
||||
|
||||
Reference in New Issue
Block a user