All Docs
FeaturesCalmony PayUpdated March 14, 2026

Security Advisory: Webhook Signature Verification Bypass (SEC-28)

Security Advisory: Webhook Signature Verification Bypass (SEC-28)

Severity: High
Fixed in: v1.0.20
Affected versions: < v1.0.20
Affected endpoint: POST /v1/checkout/sessions/callback
CVE: Pending


Summary

A logic flaw in the Cardstream checkout session callback handler allowed the HMAC-SHA512 signature verification step to be bypassed entirely by omitting the signature field from the POST request body. An unauthenticated attacker could exploit this to mark a checkout session as successfully paid using fabricated payment data.


Vulnerability Details

Root Cause

The signature verification guard in src/app/api/v1/checkout/sessions/callback/route.ts was structured as a compound conditional:

if (signatureKey && fields.signature) {
  // HMAC-SHA512 verification
}

Because the condition checked for the presence of fields.signature before verifying it, a request that simply omitted the signature field would cause the entire verification block to be skipped. Execution continued to session completion logic without any authentication.

Attack Vector

An attacker with knowledge of a valid session_id could send a crafted POST request:

POST /v1/checkout/sessions/callback?session_id=cs_live_xxxxxxxxxxxx
Content-Type: application/x-www-form-urlencoded

responsecode=0&amount=9999&currencycode=826

By omitting the signature field, the HMAC check was bypassed. The handler would process the callback as a legitimate Cardstream response, potentially marking the session as paid and triggering downstream fulfilment logic.

Impact

  • Payment sessions could be completed without a real charge being processed.
  • Downstream fulfilment, subscription activation, or invoice generation logic could be triggered fraudulently.
  • No valid Cardstream credentials or signature key were required by the attacker.

Fix

The verification logic has been updated so that when signatureKey is configured, the presence of a valid signature field is mandatory. A missing or invalid signature now results in an immediate rejection:

if (signatureKey) {
  if (!fields.signature || !verifySignature(fields, signatureKey)) {
    return new Response(
      JSON.stringify({ error: 'Invalid or missing callback signature' }),
      { status: 400 }
    );
  }
}

This ensures:

  1. When signatureKey is set, all callbacks must carry a valid HMAC-SHA512 signature.
  2. A missing signature field is treated as a verification failure, not a skippable condition.
  3. No silent fallthrough to session completion logic is possible without a verified signature.

Action Required

For Calmony Pay operators

  • Update to v1.0.20 immediately. No configuration changes are required — the fix is applied server-side.
  • Confirm that signatureKey is set in your production environment. If it is unset, signature verification will remain inactive (this is unchanged behaviour for development environments).

For integrators

  • No changes are required to your integration code.
  • Ensure your Cardstream account is configured to sign all outbound callbacks. If you are unsure, contact Cardstream support to verify your webhook signature settings.
  • Callbacks sent without a signature field will now receive a 400 Bad Request response rather than being silently accepted.

Timeline

DateEvent
IdentifiedInternal security review (SEC-28)
Fixedv1.0.20
DisclosureThis advisory

References

  • Affected file: src/app/api/v1/checkout/sessions/callback/route.ts
  • Internal control: SEC-28
  • Cardstream HMAC Signature Documentation — refer to your Cardstream integration guide for details on callback signing.