Webhook signature verification

    What is webhook signature verification?

    SHORT ANSWER

    Webhook signature verification is how your app confirms that an incoming webhook, such as a Stripe payment notice, really came from that service and wasn't made up by someone else. The service signs each message with a secret, and your app checks the signature before trusting it.

    Also called: Webhook secret

    ON THIS PAGE

    What it means

    A webhook is just a web address on your server that another service calls, for example to say "this customer has paid". Anyone who knows the address can call it too, pretending to be that service.

    Verifying the signature proves the message is genuine and unchanged. Without it, someone can send a fake "payment successful" message and get your product for free.

    Why it matters for vibe-coded apps

    AI tools usually get the webhook working and move on, so the handler happily believes whatever arrives.

    IF THIS IS WRONG IN YOUR APP
    • Fake payment messages can unlock paid plans for free.
    • Attackers can trigger refunds, emails or account changes.
    • You can't tell real events from fake ones in your logs.

    Example

    A Stripe webhook that upgrades an account.

    ✕ RISKYTrusts any request sent to the address
    app.post("/webhooks/stripe", express.json(), async (req, res) => {
      if (req.body.type === "checkout.session.completed") {
        await upgradeUser(req.body.data.object.customer);
      }
      res.sendStatus(200);
    });
    ✓ SAFERVerifies the signature first
    app.post("/webhooks/stripe", express.raw({ type: "application/json" }), async (req, res) => {
      let event;
      try {
        event = stripe.webhooks.constructEvent(
          req.body,
          req.headers["stripe-signature"],
          process.env.STRIPE_WEBHOOK_SECRET
        );
      } catch {
        return res.sendStatus(400); // not from Stripe
      }
      // handle event
      res.sendStatus(200);
    });

    Verification needs the raw request body, so don't parse it as JSON before checking.

    How to check if your app has this problem

    1. 1Find each webhook route in your code and look for a signature check before any other work.
    2. 2Send a fake POST to the address (a free tool like curl works). If it's accepted and acted on, there is no check.

    The quicker way: LetMeCheck tests for this automatically, from the outside, the way an attacker would.

    Run a free scan →

    How to fix it

    1. 1Use the provider's own library to verify the signature.
    2. 2Store the webhook secret in an environment variable.
    3. 3Return an error and do nothing when the check fails.
    4. 4Ignore events you've already handled, in case of replays.
    FIX PROMPT · PASTE INTO YOUR AI TOOL

    Add signature verification to every webhook route in my app using the provider's official library and a secret read from an environment variable. Reject any request with a missing or invalid signature before doing anything else, and use the raw request body.

    Check if your app has this problem

    Paste your website and we'll check for webhook signature verification issues and other common issues in AI-built apps. Free, about a minute, and nothing on your site is changed.

    Last updated