Skip to content

Add Stripe webhook signing secret detector#4920

Open
tanishq-sf wants to merge 1 commit intotrufflesecurity:mainfrom
tanishq-sf:feat/stripe-webhook-secret-detector
Open

Add Stripe webhook signing secret detector#4920
tanishq-sf wants to merge 1 commit intotrufflesecurity:mainfrom
tanishq-sf:feat/stripe-webhook-secret-detector

Conversation

@tanishq-sf
Copy link
Copy Markdown

@tanishq-sf tanishq-sf commented Apr 24, 2026

Closes #4711

Summary

Adds a pattern-only detector for Stripe webhook signing secrets (whsec_ prefix), as requested in #4711 by @patcain-34.

These secrets are used to verify the authenticity of webhook events sent from Stripe. They don't currently have a dedicated detector — existing stripe (live API keys sk_live/rk_live) and stripepaymentintent detectors don't cover them.

Regex

\b(whsec_[A-Za-z0-9+]{32,64})

Matches the format specified in #4711 (whsec_[A-Za-z0-9+]{32}|whsec_[A-Za-z0-9+]{64}) but collapsed to a single range-quantifier for simplicity.

Keyword: whsec_
Detector type: StripeWebhookSecret = 1048

Note: trailing \b is intentionally omitted because + is a non-word character — \b would refuse to match when a secret ends with + followed by whitespace/end-of-string. The restrictive char class combined with the {32,64} greedy quantifier is sufficient to delimit matches.

Why pattern-only

Verifying a Stripe webhook secret requires a signed webhook payload (the Stripe-Signature HMAC check), which cannot be synthesized from the secret alone. There is no authenticated endpoint that accepts the secret as a standalone credential.

Files changed

  • pkg/detectors/stripewebhooksecret/ — new detector + tests
  • proto/detector_type.proto — add enum entry StripeWebhookSecret = 1048
  • pkg/pb/detector_typepb/detector_type.pb.go — corresponding enum entries
  • pkg/engine/defaults/defaults.go — register scanner in alphabetical slot between stripe and stripepaymentintent

Test plan

  • go test ./pkg/detectors/stripewebhooksecret/ passes (4 cases: 32-char base64-style, 64-char with uppercase + +, 63-char stripe-cli-style hex, invalid)
  • go build ./... succeeds
  • Verified end-to-end against a real key from stripe listen — detector fires with Detector Type 1048
  • CI passes

🤖 Generated with Claude Code


Note

Medium Risk
Adds a new detector type and registers it in defaults, which expands scanning behavior and updates the shared DetectorType enum used by downstream consumers. Main risk is unintended false positives/negatives from the new whsec_ regex and any compatibility expectations around protobuf enum changes.

Overview
Adds a new pattern-only detector stripewebhooksecret to flag Stripe webhook signing secrets matching whsec_[A-Za-z0-9+/]{32,64}, including deduped matches and unit tests covering valid/invalid formats.

Registers the new scanner in defaults.go so it runs by default, and extends the protobuf DetectorType enum (and generated Go bindings) with StripeWebhookSecret.

Reviewed by Cursor Bugbot for commit 7832668. Bugbot is set up for automated code reviews on this repo. Configure here.

@tanishq-sf tanishq-sf requested a review from a team April 24, 2026 01:52
@tanishq-sf tanishq-sf requested review from a team as code owners April 24, 2026 01:52
Comment thread proto/detector_type.proto Outdated
Comment thread pkg/detectors/stripewebhooksecret/stripewebhooksecret.go Outdated
Comment thread pkg/detectors/stripewebhooksecret/stripewebhooksecret.go Outdated
@tanishq-sf
Copy link
Copy Markdown
Author

Linked to #4711 (the originating feature request from @patcain-34). This PR implements the regex they proposed, with the base64-style char class collapsed to a single {32,64} range quantifier.

@MuneebUllahKhan222
Copy link
Copy Markdown
Contributor

Hi @tanishq-sf,
Thanks for your contribution.

Currently, all our webhook-related detectors include a verification step to check whether the webhook is active. Could you please add similar verification logic to this Stripe webhook detector as well?

@shahzadhaider1
Copy link
Copy Markdown
Contributor

Hi @tanishq-sf, Thanks for your contribution.

Currently, all our webhook-related detectors include a verification step to check whether the webhook is active. Could you please add similar verification logic to this Stripe webhook detector as well?

Adding to this, here are some helpful resources:

@tanishq-sf
Copy link
Copy Markdown
Author

Thanks @MuneebUllahKhan222 and @shahzadhaider1 for the review!

I looked into adding an active-webhook verification step, but Stripe whsec_ secrets are a different class of credential than the other webhook detectors in the repo. Discord, Slack, Teams, and Tines detectors all match a webhook URL. The URL itself is a callable endpoint, so a GET/POST against it can confirm liveness. A Stripe whsec_ is a symmetric HMAC signing secret used server-side to verify signatures on events Stripe POSTs to your app; it is not itself a callable endpoint.

Stripe exposes no API that accepts a whsec_ as a credential:

  • GET /v1/webhook_endpoints authenticates with an sk_* API key, not the webhook secret.
  • The secret field is only returned at endpoint-creation time; it is not retrievable for existing endpoints (Stripe docs).

So a whsec_ cannot be independently verified against Stripe. I've added a comment on FromData documenting this so it doesn't come up again. Happy to revisit if there's a verification approach I'm missing.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 0a62aea. Configure here.

Comment thread pkg/detectors/stripewebhooksecret/stripewebhooksecret.go Outdated
Adds a pattern-only detector for Stripe webhook signing secrets
(whsec_ prefix). These secrets are used to verify the authenticity
of webhook events sent from Stripe.

Closes trufflesecurity#4711.

Regex: \b(whsec_[A-Za-z0-9+/]{32,64})

Uses the standard base64 alphabet [A-Za-z0-9+/] per the Standard
Webhooks spec, covering both 32-char and 64-char (and intermediate
stripe-cli) shapes. The trailing \b is intentionally omitted because
'+' and '/' are non-word characters that would break the boundary.

Detection is pattern-only because verifying a Stripe webhook secret
requires a signed webhook payload (Stripe-Signature HMAC check),
which cannot be synthesized from the secret alone. Stripe exposes no
API that accepts whsec_ as a credential: GET /v1/webhook_endpoints
authenticates with sk_* keys, and the secret field is only returned
at endpoint creation time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tanishq-sf tanishq-sf force-pushed the feat/stripe-webhook-secret-detector branch from ab9f363 to 7832668 Compare May 8, 2026 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for Stripe Webhook Secret

3 participants