Sample report

Real output. Real proof. This is what €9.99 buys.

This is a full example ShipCheck report for a fictional app, myapp.vercel.app. Every blocker below ships with redacted proof — not an opinion.

SHIPCHECK REPORT — myapp.vercel.app — 2026-07-24

🔴  Do not ship. 3 blockers found.
1

Who can read your data

BLOCKER

An unauthenticated GET to /api/customers returned 3 full rows (email, plan, stripe_customer_id) with no session cookie and no API key. The endpoint has no auth middleware.

01 · Proof (before)

3 customer rows including email, plan — returned to an anonymous request. Nobody was logged in.

02 · The fix

fix/shipcheck-data_read-2026-07-24

Adds session verification before the query and returns only the fields the signed-in customer owns.

03 · Proof (after)

Anonymous request now returns 401. Account A sees only Account A. ✓ verified on preview

2

The two-account leak test

pass

Two disposable test accounts were created. Account A requested /api/orders?userId=<account-b-id> while authenticated as Account A. The server correctly rejected the mismatched userId.

Account A could not read Account B's orders.

3

The bill that lands on you

BLOCKER

The /api/generate endpoint answered 15 consecutive requests in under 4 seconds with no rate limiting, no per-IP throttle, and no auth check. At current token pricing this extrapolates to roughly $200 per 10,000 requests, billed directly to the connected API key.

01 · Proof (before)

AI endpoint answered 15/15 requests. No rate limit found. ~$200 per 10,000 requests, billed to you.

02 · The fix

fix/shipcheck-cost_ratelimit-2026-07-24

Requires a signed-in user and adds a strict per-account limit before the paid API call runs.

03 · Proof (after)

Requests 1–5 complete. Request 6 returns 429 without calling the paid API. ✓ verified on preview

4

The money path

pass

A forged Stripe webhook payload (checkout.session.completed, no valid signature) was sent to /api/webhooks/stripe. The endpoint verified the signature and rejected the event with a 400.

Webhook rejected a forged "payment succeeded" event.

5

Can anyone find you

BLOCKER

The homepage has no <title>, no meta description, and no og:image. Sharing the link in Slack, X, or Product Hunt renders a blank grey box with the raw URL as the only text.

01 · Proof (before)

No preview title, description or image. Your launch post is invisible.

02 · The fix

fix/shipcheck-discoverability-2026-07-24

Adds page metadata, a 1200×630 share image, sitemap, robots rules, and a useful 404.

03 · Proof (after)

Title, description and share image render in raw HTML. Crawler checks pass. ✓ verified on preview

Fixes ready on branches

  • fix/shipcheck-data_read-2026-07-24
  • fix/shipcheck-cost_ratelimit-2026-07-24
  • fix/shipcheck-discoverability-2026-07-24

Merge, redeploy, re-run. That's what turns this green.

Needs a human

Exposed secret #1 was found in the browser bundle.

ShipCheck will not print it, move it, or delete it. A leaked key must be rotated at its source — removing the old string from code does not make the old key safe.

  1. 1

    Open the provider dashboard.

  2. 2

    Create a replacement key.

  3. 3

    Store it as a server-side secret.

  4. 4

    Redeploy and verify the app.

  5. 5

    Revoke exposed secret #1.

Rotate. Verify. Then revoke. Do not just delete the string.

What was cleaned up

  • 2 test accounts deleted
  • 1 forged test webhook reverted
  • 0 rows written

Get the sample report + the pre-launch checklist. No spam.

Made with AI in Macaly