IS RORK SAFE? SECURITY ANALYSIS | VIBEEVAL
Is Rork safe? The short answer
Rork the platform is safe. Apps built with Rork are safe when the developer moves enforcement to the backend, because on mobile the client cannot be trusted at all. Rork generates real React Native + Expo apps wired to hosted backends like Supabase or Firebase. Everything in that app bundle — keys, endpoints, logic — is extractable from the APK/IPA, so any check that lives only in the client is decoration. The generated apps consistently ship with backend rules unfinished, tokens in plaintext storage, and entitlements gated in app code. Each gap is fixable in minutes; collectively they are the difference between a demo and something you can put in the app stores.
The Rork generation pattern
Rork generates working mobile apps quickly. The AI prioritizes “this runs on my phone” over “this survives a hostile client.” That has a predictable cost, and on mobile the cost is amplified because the client binary is public:
- Enforcement lands in the client. Role checks, premium gates, and validation get generated as React Native conditionals — visible, extractable, patchable.
- Backend rules lag the schema. New tables and collections appear as you prompt; RLS policies and Firestore rules don’t follow automatically.
- Tokens go to AsyncStorage. The generated auth flow persists sessions in unencrypted storage instead of SecureStore/Keychain.
- Generated APIs skip auth. CRUD functions return whatever’s asked for by ID — the classic BOLA shape.
- Deep links trust their input. Handlers accept unvalidated parameters, including redirect targets.
- Secrets ride along. When a server key is in reach, the generator embeds it, and a shipped binary can’t be un-shipped.
These are not bugs in Rork; they are characteristics of AI generation pointed at a platform where the client is public by definition. Knowing the pattern is the entire fix — each audit area below targets one failure mode.
The 6 areas to harden in every Rork app
1. Backend rules — the real auth boundary
The Supabase anon key or Firebase config in your bundle is fine to ship ONLY if the backend enforces access on every table. This is the load-bearing control for the whole app.
Fix. Enable RLS on every Supabase table with owner-scoped policies:
alter table projects enable row level security;
create policy "owners read own rows"
on projects for select
using (auth.uid() = owner_id);
create policy "owners write own rows"
on projects for all
using (auth.uid() = owner_id)
with check (auth.uid() = owner_id);
For Firestore, the equivalent per collection:
match /projects/{id} {
allow read, write: if request.auth != null
&& request.auth.uid == resource.data.owner_id;
}
“Authenticated” alone is not a scope — that’s every user of your app reading every other user’s rows. Verify from outside with the Supabase RLS Checker or Firebase Scanner.
2. Secrets out of the bundle
Every string in the APK/IPA is extractable. Publishable keys are designed for that; server secrets are not — and mobile’s twist is that a leaked secret in a released binary stays leaked until users update. There is no instant rotation for a shipped app.
Fix. Audit the source and the built bundle before every release:
grep -rE 'sk_(live|test)_|sk-[A-Za-z0-9]{20,}|service_role|AIza[A-Za-z0-9_-]{35}' . \
--exclude-dir=node_modules --exclude-dir=.git
Anything that matches moves behind a server-side function. Rotate any value that ever shipped.
3. Token storage
AsyncStorage is plaintext. Session tokens belong in the platform keystore.
Fix. Swap generated persistence to expo-secure-store:
import * as SecureStore from "expo-secure-store";
await SecureStore.setItemAsync("session_token", token);
const token = await SecureStore.getItemAsync("session_token");
If Supabase auth is in play, pass a SecureStore-backed adapter as the client’s storage option so the SDK never touches AsyncStorage.
4. Server-side entitlements and receipt verification
Client-side premium checks are flippable in a patched binary. The store receipt is the only trustworthy purchase evidence, and only the server should evaluate it.
Fix. The flow: client completes the purchase, sends the receipt to your backend; the backend verifies it against Apple/Google, writes the entitlement to the database; backend rules gate premium data on that flag. The client renders is_premium — it never decides it.
// Server-side sketch
const verdict = await verifyReceiptWithStore(receipt); // Apple/Google API
if (verdict.valid) {
await db.entitlements.upsert({ user_id, product: verdict.productId });
}
5. Generated API routes — auth then ownership (BOLA)
Attackers extract your API endpoint from the bundle and call it directly, so every generated route needs an auth check and an ownership check. See BOLA in AI-generated CRUD for the full pattern.
Fix. In every ID-keyed function:
const { data: project } = await supabase
.from("projects").select().eq("id", id).single();
if (!project) return notFound();
if (project.owner_id !== user.id) return forbidden();
Manual test: two accounts, user B requests user A’s record ID directly against the API. Anything but 403/404 is the finding.
6. Deep links and app entry points
Deep links are attacker-reachable input — anyone can send your users a crafted app:// URL.
Fix. Validate every parameter, allowlist redirect targets, and never derive auth state from a link. Prefer verified universal links (iOS) / app links (Android) over raw custom schemes for anything security-relevant, since custom schemes can be claimed by other apps.
The mobile difference — why day one matters more
On the web, a leaked key is a redeploy away from fixed. On mobile, the binary you shipped is on users’ devices until they update, and store review sits between you and the fix. That inverts the priority order: bundle hygiene and backend enforcement are not “harden later” items — they are the launch gate. Anything enforced server-side can be fixed tomorrow; anything wrong in the binary is wrong for weeks.
Pre-release Rork checklist
- RLS enabled on every Supabase table (or rules on every Firestore collection), owner-scoped.
- No server secrets in source or the built bundle; publishable keys only.
- Session tokens in SecureStore, not AsyncStorage.
- Purchases verified server-side against store receipts; entitlements in the database.
- Every generated API route checks auth, then ownership.
- Deep link parameters validated; redirects allowlisted.
- Privileged fields (
role,is_premium) not writable by the client. - Rate limits server-side on auth and expensive endpoints.
- Run VibeEval against the backend your app calls for the dynamic pass.
Rork vs web app builders — security positioning
- Rork. Mobile-first React Native + Expo. Failure modes concentrate in bundle extraction, backend rules, token storage, and client-trusted logic — and shipped mistakes persist until users update.
- Web builders (Lovable, Bolt, Base44). Same generated-code failure modes, but the client is a redeployable web bundle: leaks are fixable instantly, and there’s no store-review lag.
The generated-code habits are the same; mobile raises the stakes on shipping them.
The verdict
Rork produces working cross-platform mobile apps remarkably fast. Security is not what it optimizes for, and mobile is unforgiving about that: the bundle is public, the client is patchable, and released mistakes linger. Treat every Rork app as needing a pre-release review — backend rules, bundle hygiene, token storage, receipt verification, route-level auth, deep link validation. The list is mechanical and scannable. Run it before every store submission.
Related resources
- How to Secure Rork — step-by-step hardening guide
- Rork Security Checklist — pre-launch checklist
- Supabase RLS Checker — verify the anon key is safe to ship
- Firebase Scanner — probe Firestore rules from outside
- Vibe Code Scanner — automated scan for the backend your app calls
- Vibe Coding Vulnerabilities — full vulnerability taxonomy across AI tools
Scan your Rork app
Let VibeEval scan the backend your Rork application ships its keys for — the open-rules, BOLA, and credential-leakage patterns that AI generators most often leave in.
COMMON QUESTIONS
SCAN YOUR APP
14-day trial. No card. Results in under 60 seconds.