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¤cycode=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:
- When
signatureKeyis set, all callbacks must carry a valid HMAC-SHA512 signature. - A missing
signaturefield is treated as a verification failure, not a skippable condition. - 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
signatureKeyis 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
signaturefield will now receive a400 Bad Requestresponse rather than being silently accepted.
Timeline
| Date | Event |
|---|---|
| Identified | Internal security review (SEC-28) |
| Fixed | v1.0.20 |
| Disclosure | This 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.