Michael Bires

Case study

Documented public incident

Documented: Stripe Bypass on Linkable (CVE-2025-48757 Follow-Up)

Based on publicly reported incidents with linked sources — not a fictional client narrative. Describes the real problem and how I fix the same pattern for paying clients.

Subject

Documented: Linkable (linkable.site) — Lovable marketing product

Stack

Lovable, Supabase REST API, Stripe integration

Outcome

Unauthorized POST set payment_status=paid; legitimate webhooks fail for same RLS/env reasons

This case study covers a verified public incident from the CVE-2025-48757 disclosure — not a made-up founder narrative. The payment bypass on Linkable is the extreme version of a failure mode I see weekly: money moves in Stripe, but the app database never updates correctly.

The documented incident: payment_status bypass

Context: Linkable (linkable.site) was a Lovable-built site — later a paid product actively maintained by a Lovable employee.

May 24, 2025 follow-up by security researcher Matt Palmer:

  • The data endpoint had moved to /rest/v1/website_generation.
  • RLS appeared to work only when an auth header was present.
  • Removing the auth header switched the request to the unauthenticated security context — bypassing access controls entirely.
  • Palmer issued a POST with a crafted payload including "payment_status": "paid".
  • The record was accepted. Stripe was never involved.

This is cited in Palmer's statement with a sample payload (anonymized emails) and screenshot of the request. It demonstrates that broken RLS on payment-related tables is not theoretical — it was reproducible on a first-party Lovable product after the initial March disclosure and after Lovable shipped a "security scan" in April 2025.

The everyday founder version (same root causes)

Most founders don't discover this via security research. They discover it via support tickets:

"I paid in Stripe but my app still shows free tier."

That legitimate failure — Stripe Checkout succeeds, app state unchanged — usually traces to one of:

  1. Webhook URL on preview/localhost after deploy to production.
  2. Wrong webhook signing secret in Supabase Edge Function env (constructEvent returns 400).
  3. RLS blocking the webhook handler's database insert (handler uses anon key instead of service role).
  4. Missing event subscriptions (checkout.session.completed, customer.subscription.updated).

The Lovable Stripe docs describe the happy path; community threads (r/lovable — Stripe subscriptions, payment integrations discussion) document where it breaks in production.

Superblocks' analysis of CVE-2025-48757 specifically notes: "One of the most striking cases came from public Stripe integration endpoints. Attackers could override payment settings or inject unauthorized parameters."

How I fix this pattern (my engagement)

Triage first: Stripe Dashboard → Webhooks → recent deliveries. The HTTP status and response body beat another AI prompt.

Typical fixes (Priority Fixes $799):

  • Production webhook endpoint + live signing secret in server-side secrets.
  • Webhook handler on service role with idempotency on event.id.
  • RLS policies that allow server-side writes but not public reads on subscriptions / orders.
  • One live-mode test transaction end-to-end.

For apps that may have been exposed (Linkable-class bugs): external anon-key curl test on payment tables before go-live.

What you should search to verify

  • CVE-2025-48757 linkable payment_status
  • matt palmer linkable stripe bypass
  • lovable stripe webhook not working reddit

Sources


Stripe shows paid but your app doesn't? Webhook troubleshooting guide or contact me.

Primary sources

Facing something similar right now?

Tell me what broke and get a fixed-price answer — usually within 48 hours for triage.

Get help with this