DATABUTTON SECURITY CHECKLIST
Databutton is an AI app builder whose agent generates a React frontend and a Python FastAPI backend, deployed and hosted on the platform. The most common security issues come from two patterns: generated FastAPI endpoints ship without auth dependencies unless you asked for them, and third-party API calls sometimes land in the React code, which puts the key in the browser bundle. The checklist below is what we look for first when we audit a Databutton app.
Treat Critical as launch-blocking. High is week-one. Medium is the cleanup once you have users.
How to use this checklist
Walk it once against the generated code and a second logged-in user account, ticking items as you go. After each fix, sign in as user B and try to read user A’s data. After the whole list passes, run a black-box scan against the deployed URL.
Critical (fix before launch)
1. Add an auth dependency to every FastAPI route
Why it matters. The agent generates working endpoints, and working does not include auth. A route without an auth dependency is publicly callable at the deployed URL — no session, no token, no login.
How to check. Read every router. Any route handling user data whose signature lacks a Depends(get_current_user)-style parameter is open. Then confirm from outside: call the endpoint with curl and no token — you should get 401, not 200.
How to fix. Add a shared auth dependency that verifies the caller’s token (Firebase Auth ID token or equivalent) and attach it to every protected route — or to the whole router via dependencies=[Depends(get_current_user)] so a new route can’t ship open.
2. Add ownership checks on every ID-keyed route
Why it matters. Auth alone means “any logged-in user.” Generated CRUD looks up by ID and returns whatever it finds, so user B can fetch user A’s records by changing the ID. This is BOLA, the most common finding in AI-generated backends.
How to check. Sign in as user A, note a record ID, sign in as user B, and request that ID. The response must be 403 or 404, not 200.
How to fix. After every lookup, compare the record’s owner field to the authenticated user and return 403/404 on mismatch. See BOLA in AI-generated CRUD.
3. Move every third-party API call server-side
Why it matters. Databutton has a secrets store, but it only protects keys that stay in the FastAPI backend. Generated code sometimes calls OpenAI, Stripe, or another provider directly from React — the key ships in the JavaScript bundle where anyone can extract it.
How to check. Search the frontend source for sk-, sk_live_, re_, AIza, and any fetch to a third-party API host. Then check the deployed bundle itself with the Token Leak Checker.
How to fix. Route every third-party call through a FastAPI endpoint that reads the key from the secrets store. Rotate any key that ever shipped in the bundle.
4. Fix the CORS middleware
Why it matters. Generated FastAPI apps commonly ship CORSMiddleware with allow_origins=["*"] and allow_credentials=True. Any website can then make credentialed requests to your API from a visitor’s browser.
How to check. Find the add_middleware(CORSMiddleware, ...) call. If origins is ["*"] (or reflects the request origin) while credentials are allowed, it’s misconfigured.
How to fix. Allowlist your production origin only. See CORS + credentials misconfig.
5. Forbid extra fields in write models (mass assignment)
Why it matters. Pydantic models exist in the generated code, but write endpoints sometimes accept extra fields or reuse the full model for updates. A user PATCH’ing their profile with "is_admin": true or a client-supplied owner_id can escalate or reassign records.
How to check. For every create/update model, confirm extra="forbid" (or explicit field whitelisting) and confirm owner, role, and admin fields never come from the request body.
How to fix. Separate input models from database models. Set ownership and role server-side from the authenticated user, never from the payload.
6. Disable FastAPI docs endpoints in production
Why it matters. /docs, /redoc, and /openapi.json are on by default and enumerate your entire API surface — every route, parameter, and model. That’s a reconnaissance map for the unauthenticated endpoints from item 1.
How to check. Open https://your-app-url/docs and /openapi.json in a logged-out browser.
How to fix. FastAPI(docs_url=None, redoc_url=None, openapi_url=None) for the deployed app.
High (fix in the first week)
7. Rate-limit LLM-calling and expensive endpoints
Any endpoint that calls an LLM or a metered API needs a per-user limit — one user with a loop can run up your bill in minutes. Add per-IP limits on auth endpoints as well.
8. Return generic errors in production
FastAPI’s default validation errors and unhandled exceptions echo field names and internal structure. Add an exception handler that logs server-side and returns a generic message to clients.
9. Verify Firebase Auth tokens server-side
If auth runs through Firebase Auth, the backend must verify the ID token’s signature and audience — not just decode it. Restrict authorized domains in the Firebase console to your production domain.
10. Harden scheduled jobs
Scheduled tasks run with your backend’s privileges. Confirm they pull secrets from the secrets store, validate anything they ingest from external sources, and don’t write attacker-influenced content into user-visible data.
11. Verify webhook handlers check signatures
Stripe, Resend, and GitHub all sign webhooks. Generated handlers usually read the event body and act on it without verifying the signature — fix this before payments go live.
12. Disable email enumeration in the auth flow
Confirm signup, password reset, and magic link return identical responses for “user exists” and “user does not exist.”
Medium (fix when you can)
13. Validate file uploads
If the agent generated an upload flow: size cap, MIME allowlist, regenerated filenames. See file upload zip-slip / XXE.
14. Sanitize user content before rendering
User- or LLM-generated text rendered as HTML/Markdown in the React app is stored XSS unless sanitized. See LLM-rendered HTML/Markdown.
15. Audit secrets store contents
Walk the secrets store: remove keys for services you no longer use, and confirm no secret is duplicated as a hardcoded fallback in the source.
16. Restrict who can edit the app
Anyone with edit access to the Databutton workspace can change endpoints, secrets usage, and scheduled jobs. Audit the collaborator list.
17. Document each endpoint’s access model
Keep a written record of which routes require auth, which check ownership, and why. When the agent regenerates code, you have something to diff against.
18. Set up monitoring for unusual access patterns
Watch the backend logs for ID enumeration (sequential 403/404s from one caller), repeated 401s on auth endpoints, and traffic spikes on LLM endpoints.
After every Databutton regeneration
- Re-check that auth dependencies survived on every route the agent touched.
- Re-run the two-account BOLA test on regenerated CRUD.
- Grep the frontend for new third-party calls or embedded keys.
- Confirm CORS middleware wasn’t reset to allow-all.
- Confirm docs endpoints are still disabled in the deployed app.
Common attack patterns we see in Databutton apps
The open endpoint. A generated /routes/orders router with no auth dependency; anyone who reads /openapi.json dumps every order.
The bundled API key. The agent wired an OpenAI call into a React component; the key ships in the JS bundle and gets scraped within days.
The trusting PATCH. The update endpoint reuses the full Pydantic model; a user sets is_admin: true on their own profile.
The credentialed CORS hole. Allow-all origins with credentials lets a malicious page read a logged-in visitor’s data through their own browser.
Related Resources
How to Secure Databutton
Step-by-step guide for hardening a Databutton app — auth dependencies, ownership checks, secrets hygiene, and CORS in long form.
Is Databutton Safe?
In-depth analysis of Databutton’s defaults — what the platform handles, what the generated code leaves open, and what we find when we audit a typical app at launch.
Automate Your Checklist
A checklist tells you what to look for. A scanner tells you what’s actually broken in the deployed app right now. VibeEval drives a real browser through your Databutton deployment, attempts the cross-user BOLA, mass-assignment, and unauthenticated-endpoint attacks above, and reports what got through — with the route to fix.
SCAN YOUR DATABUTTON APP
14-day trial. No card. Results in under 60 seconds.