1
Who can read your data
BLOCKERAn 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-24Adds 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
passTwo 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
BLOCKERThe /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-24Requires 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
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
BLOCKERThe 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-24Adds 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
6
Can your AI be tricked
passThe app has an AI feature, so ShipCheck tried whether a stranger could make it break its rules, spill its secret instructions, or leak data. If the app had no AI, this check would say "no AI integration found" and move on.
✓ Prompt-injection attempts did not reveal secret instructions or private data.
7
Can someone break into an account
passUsing only a throwaway address created for this run, ShipCheck checked whether the app reveals which emails have accounts, slows down password guessing, and rejects a password-reset link after it has been used once.
✓ The app did not reveal registered emails, slowed repeated guesses, and rejected a reused reset link.
8
Does your app trust the browser
passShipCheck sent invalid input directly to the running app without using its form, checked that errors did not expose database details, and checked whether unrelated websites could call the API from a signed-in browser.
✓ Server-side checks rejected invalid input without exposing database details.
9
Are you covered legally
passShipCheck checked for a reachable privacy policy, where data lives and who else handles it, consent before tracking, and copyleft licences included in the project. This is a self-audit check, not legal advice.
✓ Privacy information was reachable, tracking waited for consent, and no unreviewed copyleft licence was found.