RepoVerdict Request an audit
Explore RepoVerdict
Fictional sample.Huurly is not a real customer. All code and findings are illustrative.

Sample report

Technical due diligence — Huurly

Fictional short-term rental app · Lovable + Supabase · 61 example files reviewed

REPAIR

Targeted fixes are recommended before launch, especially ownership checks and payment-event handling. Database isolation must also be verified. The supplied evidence does not justify a full architectural rebuild.

How to read this report

Numerical scores have been removed: the original sample did not define a reproducible scoring formula. Severity and evidence status drive this recommendation.

P0: address before launch. P1: important risk or verification gap. P2: valuable improvement. P3: optional maintenance improvement. A severity label on a verification gap indicates priority to investigate, not a proven exploit.

Effort figures are illustrative implementation estimates, not fixed quotes or elapsed delivery promises. Overlapping findings and executive summaries are not counted twice for the audit guarantee.

01 / 12

Authentication & authorization

Missing ownership check

P0

Confirmed in example code; effective database authorization still needs verification.

Evidence
app/api/listings/[id]/route.ts (PATCH)
const user = await getUser();
await supabase.from('listings').update(body).eq('id', params.id);
Impact

The route checks login but does not constrain the update to the listing owner. If no lower-layer policy blocks it, another user could edit the listing.

Recommendation

Validate allowed fields, constrain the update to the owner, and verify database policies. Test an attempted cross-user update.

Illustrative effort: 20–60 minutes

No application-level login rate limit

P2

Code observation; provider-level controls not verified.

Evidence
app/api/auth/login/route.ts — no local limiter around supabase.auth.signInWithPassword()
Impact

Repeated login attempts may reach the authentication provider without application-level throttling.

Recommendation

Verify provider limits; add appropriate throttling and abuse monitoring without locking out legitimate users.

Illustrative effort: 30 minutes
02 / 12

Database & row-level security

RLS activation not evidenced for customer_addresses

P1

Verification required; live exposure is not confirmed.

Evidence
supabase/migrations/0007_addresses.sql — CREATE TABLE customer_addresses (...)
No subsequent ENABLE ROW LEVEL SECURITY or policy found in supplied migrations.
Impact

Customer-address isolation cannot be established from the repository alone. Database grants, deployed settings and effective policies were not supplied.

Recommendation

Inspect deployed RLS status and grants. If missing, enable RLS and add owner-scoped policies in a migration. Test cross-user reads and writes.

Illustrative effort: 20–60 minutes

guest_reviews policy has no confirmed activation

P1

Verification required; live exposure is not confirmed.

Evidence
supabase/migrations/0011_reviews.sql — CREATE POLICY "reviews_select" ON guest_reviews ...
No ENABLE statement found.
Impact

A policy existing in migrations does not establish that RLS is enabled in production.

Recommendation

Verify effective configuration and reproduce the required settings in migrations.

Illustrative effort: 10–30 minutes
03 / 12

Secrets & key management

A secret-like Stripe key remains in Git history

P1

Repository evidence; key validity not tested.

Evidence
git log --all --full-history -- .env
Illustrative commit 3a1f9c2 — STRIPE_SECRET_KEY=sk_live_…
Impact

Deleting the file from the current tree does not remove historical access. The redacted sample is not a real credential.

Recommendation

Treat the real key as exposed: rotate it immediately, review usage and coordinate history cleanup. History cleanup alone does not revoke a key.

Illustrative effort: 40 minutes

Service-role usage needs a maintenance note

P3

No client-side exposure identified in the supplied example.

Evidence
supabase/functions/send-confirmation/index.ts — service-role key used server-side
Impact

Future changes could accidentally move privileged logic into the client.

Recommendation

Document the trust boundary and add a regression check against client-side secret exposure.

Illustrative effort: 5–20 minutes
04 / 12

APIs & webhooks

Public inquiry route accepts an unvalidated body

P1

Confirmed in example handler.

Evidence
app/api/inquiries/route.ts
await supabase.from('inquiries').insert(await req.json())
Impact

Unexpected fields and malformed values reach the database operation. Database constraints and grants were not verified.

Recommendation

Validate a bounded schema server-side, allowlist fields and reject unexpected values.

Illustrative effort: 25 minutes

No application-level limits found on public routes

P2

Code observation; edge controls not supplied.

Evidence
/api/inquiries and /api/listings/search — no application limiter found
Impact

Public endpoints may be susceptible to spam or scraping, depending on upstream controls.

Recommendation

Verify platform controls and apply shared request limits appropriate to each route.

Illustrative effort: 30 minutes
05 / 12

Payments & billing

Stripe webhook lacks event deduplication

P0

Confirmed missing guard in the fictional handler.

Evidence
app/api/webhooks/stripe/route.ts — checkout.session.completed processed without a unique event claim
Impact

Retries may process an order or grant entitlements twice. Duplicate charges are not established by this evidence.

Recommendation

Atomically claim the event, make business effects retry-safe, handle failures explicitly and test duplicate and concurrent deliveries.

Illustrative effort: 45–90 minutes

Checkout can create duplicate sessions

P2

UI observation; server idempotency not shown.

Evidence
components/CheckoutButton.tsx — no pending or disabled state during the checkout request
Impact

A rapid double click may create multiple sessions; it does not by itself prove a second payment.

Recommendation

Disable repeated UI actions while pending and enforce server-side idempotency for checkout creation.

Illustrative effort: 15–45 minutes
06 / 12

Architecture & scalability

Search route combines multiple responsibilities

P2

Maintainability observation.

Evidence
app/api/listings/search/route.ts — a 184-line exported handler
Impact

Combined query, filtering and sorting logic makes changes and testing harder. Length alone is not a security finding.

Recommendation

Separate reusable query logic where it improves clarity and add behavior-focused tests.

Illustrative effort: 90 minutes
07 / 12

Performance

Sequential profile queries in listings page

P1

Code-based performance finding; not load-tested.

Evidence
app/(public)/listings/page.tsx
for (const listing of listings) {
  await supabase.from('profiles').select().eq('id', listing.owner_id);
}
Impact

Each listing adds a sequential database call, increasing latency as the result grows.

Recommendation

Use an appropriate join or batch lookup, then measure behavior with representative data.

Illustrative effort: 40 minutes
08 / 12

Code quality & duplication

Validation duplicated across six routes

P2

Maintainability observation.

Evidence
app/api/inquiries/route.ts, app/api/bookings/route.ts and four other example routes — repeated email and phone expressions
Impact

Validation changes can diverge between routes.

Recommendation

Extract shared schemas and retain route-specific rules explicitly.

Illustrative effort: 45 minutes
09 / 12

Test coverage

No payment-flow tests found

P1

Repository observation, not a measured coverage percentage.

Evidence
No supplied test exercises the Stripe webhook or checkout flow.
Impact

The duplicate-event behavior is not protected by a regression test.

Recommendation

Test a repeated Stripe event, concurrent deliveries and retry after a failed business operation.

Illustrative effort: 90 minutes

No cross-user authorization test found

P1

Repository observation.

Evidence
No supplied test exercises ownership enforcement on app/api/listings/[id]/route.ts.
Impact

An authorization regression could go unnoticed.

Recommendation

Test that one user cannot update another user’s listing, including through database access paths.

Illustrative effort: 60 minutes
10 / 12

Deployment & environments

No separate staging setup evidenced

P2

Verification required; dashboard settings not supplied.

Evidence
vercel.json and .env.example — no separate staging project documented
Impact

The repository alone cannot establish whether isolated preview infrastructure exists.

Recommendation

Confirm deployment settings and document an isolated environment for payment and access-control testing.

Illustrative effort: 60 minutes
11 / 12

Monitoring & logging

No centralized error tracking evidenced

P1

Code observation; infrastructure logging not supplied.

Evidence
package.json — no error-tracking integration found; handlers use console.error
Impact

Critical failures may be hard to detect and correlate. The absence of a specific dependency does not prove no monitoring exists.

Recommendation

Verify infrastructure monitoring and connect critical paths to alerting with request references.

Illustrative effort: 25 minutes

Booking error logs include contact data

P2

Confirmed in example code.

Evidence
app/api/bookings/route.ts
console.error('booking failed', body)
Impact

The example body includes guest email and phone details. Log access and retention were not supplied.

Recommendation

Log a request reference and sanitized error metadata instead of the full body.

Illustrative effort: 15 minutes
12 / 12

Business risk & investment readiness

Launch readiness depends on access and payment fixes

P1

Synthesis of other findings, not an additional qualifying issue.

Evidence
See categories 01, 02, 05 and 09.
Impact

Ownership enforcement and duplicate payment-event handling require attention; effective database isolation remains unverified.

Recommendation

Fix the code paths, verify deployed database policies and add regression tests before a launch decision.

Illustrative effort: Planning plus the referenced fixes

Remediation roadmap

Fix, verify, then reassess.

  1. Before launch: enforce ownership, make webhook processing retry-safe, rotate any exposed real key and verify effective database policies.
  2. Validate the fixes: run cross-user access and payment retry tests in an isolated environment.
  3. Improve operations: monitoring, bounded input validation, appropriate rate limits and sanitized logs.
  4. Improve maintainability: query batching, shared validation and documented staging.

Scope and data gaps

What this sample does not establish.

Request your audit Compare packages