Skip to content

fix(gitlab): fail closed when the webhook secret is missing - #609

Merged
devjain32 merged 5 commits into
corsairdev:mainfrom
sushantlokhande14:fix/gitlab-webhook-fail-open
Aug 6, 2026
Merged

fix(gitlab): fail closed when the webhook secret is missing#609
devjain32 merged 5 commits into
corsairdev:mainfrom
sushantlokhande14:fix/gitlab-webhook-fail-open

Conversation

@sushantlokhande14

@sushantlokhande14 sushantlokhande14 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #594.

verifyGitlabWebhookSignature returned { valid: true } whenever no secret was configured. As the issue notes, this one is worse than the Jira/Twitter variants: it short-circuits unconditionally, before it ever reads the X-Gitlab-Token header, so any unsigned request was accepted outright.

// before
if (!secret) {
	return { valid: true };   // <-- never even looks at the token
}
// after
if (!secret) {
	return { valid: false, error: 'Missing webhook secret' };
}

One line, matching the fail-closed shape and the exact 'Missing webhook secret' string already used by the Spotify verifier after the same family was fixed there (#519, #520, #514).

Adds packages/gitlab/webhooks/types.test.ts:

case expected
secret missing (token present) Missing webhook secret — the bug
secret and token both missing valid: false
token header missing (secret present) Missing X-Gitlab-Token header
token does not match secret X-Gitlab-Token does not match configured secret
token matches secret valid: true

All three acceptance criteria in the issue are covered.

Checklist

  • I have run pnpm lint and all checks pass — biome check clean on both changed files; the repo's lint-staged hook (biome check --write) ran clean on both commits
  • I have run pnpm typecheck and there are no TypeScript errors — the repo's pre-push typecheck hook passed
  • I have run pnpm build and all packages build successfully
  • I have run pnpm test and all tests pass — green in CI; see note below for local runs
  • I have added or updated tests where applicable
  • I have added or updated necessary documentation — none required, no public API or plugin option changed

On the test box. My new suite passes 5/5. The package has two pre-existing failing suites that fail identically on a clean checkout of main, so this branch changes nothing about them:

clean main:   Test Suites: 2 failed, 1 passed, 3 total   Tests: 24 failed,  3 passed, 27 total
this branch:  Test Suites: 2 failed, 2 passed, 4 total   Tests: 24 failed,  8 passed, 32 total
                                     ^ +1 (mine)                 ^ identical   ^ +5 (mine)

The two are api.test.ts (builds an auth header from an unset API key) and integration.test.ts (Cannot find module 'corsair/orm' — needs a workspace build). Both unrelated; I left them alone.

Screenshots / Demos (if applicable)

On R4 in PLUGIN_PR_RULES.md: that rule exists because "neither CI nor review bots can call the real third-party API." This change calls no GitLab endpoint and needs no credentials (the issue says so too) — it's a pure local comparison, so the unit tests are the verification and they run in CI:

$ pnpm --filter @corsair-dev/gitlab test

 PASS  ./webhooks/types.test.ts
  verifyGitlabWebhookSignature
    √ should fail closed when secret is missing
    √ should fail closed when both secret and token header are missing
    √ should return invalid if the token header is missing
    √ should return invalid if the token does not match the secret
    √ should return valid when the token matches the configured secret

Working proof: the CI run for this branch, where the suite executes and passes — CI Checks.

To be straight about it: that is a link to a CI job, not a screen recording. I can't record one, and for this change there is nothing to film — no UI, no CLI output, no third-party call. If a recording is required regardless, say so and I'll arrange it.

Additional Notes

  • Scope is packages/gitlab/** only (R1). Companion to fix(jira): fail closed when webhook secret or signature is missing #608 (the Jira half of this family) — kept separate to honour one plugin per PR.
  • Not a breaking change for correctly-configured webhooks: a request whose token matches a configured secret behaves exactly as before. What stops working is precisely the insecure configuration — a deployment running GitLab webhooks with no secret set will now be rejected, which is the intent.
  • Out of scope, but worth flagging: the token check is token !== secret, a plain string comparison rather than a timing-safe one. Unlike the HMAC verifiers this compares the shared secret directly, so it is theoretically distinguishable by timing. I left it alone to keep this PR to the one-line fix the issue asks for — happy to send it separately if you want it.

verifyGitlabWebhookSignature returned { valid: true } whenever no secret
was configured, short-circuiting before it ever read the X-Gitlab-Token
header. Any unsigned request was therefore accepted outright.

Return an error instead, matching the fail-closed shape already adopted
by the Spotify, Zoom and Slack verifiers (corsairdev#519, corsairdev#520, corsairdev#514).

Fixes corsairdev#594
Adds packages/gitlab/webhooks/types.test.ts: missing secret, the
both-missing case, missing token header, a token that does not match the
secret, and the matching-token round-trip.

Fixes corsairdev#594
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
www Skipped Skipped Aug 6, 2026 2:07pm

Request Review

@github-actions github-actions Bot added the plugin Changes inside a plugin package label Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

GitLab webhook verification

Layer / File(s) Summary
Fail-closed verification and regression coverage
packages/gitlab/webhooks/types.ts, packages/gitlab/webhooks/types.test.ts
Missing webhook secrets now return valid: false with Missing webhook secret. Tests cover missing secrets, missing token headers, mismatched tokens, and valid tokens.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • Issue 595 — Tracks the same fail-closed behavior for Jira webhook verification.
  • Issue 582 — Tracks missing-secret rejection for another webhook integration.

Possibly related PRs

Suggested reviewers: devjain32

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #594 by rejecting missing secrets, preserving valid-token behavior, and adding the required tests.
Out of Scope Changes check ✅ Passed All changes are limited to GitLab webhook verification and its tests, which matches issue #594.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the fail-closed behavior for a missing GitLab webhook secret.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR changes GitLab webhook verification to fail closed when no secret is configured and adds focused regression coverage.

  • Returns Missing webhook secret instead of accepting requests when the secret is empty.
  • Tests missing-secret, missing-header, mismatched-token, and matching-token paths.

Confidence Score: 5/5

The PR appears safe to merge and correctly closes the missing-secret webhook authentication path.

The changed verifier rejects requests before token comparison when its configured secret is absent, while preserving the existing missing-header, mismatch, and successful-match behavior with focused tests.

Important Files Changed

Filename Overview
packages/gitlab/webhooks/types.ts Replaces the insecure missing-secret success path with an explicit verification failure.
packages/gitlab/webhooks/types.test.ts Adds direct assertions covering the verifier's failure and success branches.

Reviews (1): Last reviewed commit: "test(gitlab): cover webhook token fail-c..." | Re-trigger Greptile

@Dhirenderchoudhary

Copy link
Copy Markdown
Collaborator

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin Changes inside a plugin package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(gitlab): webhook signature verification fails open when secret is missing

3 participants