Nothing is "completely secure".
The site is anonymous and free: no accounts, no payments, no personal data collected. That removes a lot of risk before any code is written.
Architecture: Cloudflare Workers (static frontend) -> Render (FastAPI backend) -> Supabase PostgreSQL + Cloudflare R2 for photos.
- Every query is parameterised (
%splus a tuple). No SQL is assembled by string formatting anywhere. - User input only reaches a query through Pydantic-validated fields.
.envis gitignored and nothing is hard-coded.- Render and GitHub Actions hold their own secrets, none of which live in the repo.
- Row Level Security is enabled on
carsandsearcheswith no policies, which closes Supabase's automatic REST API to anonymous callers by default-deny. - The backend connects directly as the owner role, which bypasses RLS, so it is unaffected.
- A cooldown between searches plus an hourly limit, keyed on an anonymous browser
token with the IP as a backstop (
src/api/rate_limit.py). - The client IP is read from
cf-connecting-ip, which Cloudflare overwrites and a client therefore cannot forge. without Cloudflare it falls back tox-forwarded-for.
- Only the real frontend origin and the local dev ports are allowed, with
allow_credentials=Falseand onlyGET/POST.
- Pydantic bounds everything:
queryis capped at 200 characters,pageat 1-200,yearat 1900-2030, and so on. Absurd or oversized input is rejected before it reaches the endpoint.
- API errors return a machine code (
{"code": ...}) rather than internal detail. the frontend turns that into a message in the user's language. - In production the global exception handler never exposes a stack trace on a 500
(
IS_PRODUCTION).
- Photos are only fetched from the known source CDNs (autopapa, myauto) and written to R2. A user cannot get the backend to fetch an arbitrary URL.