Skip to content

Rule catalogue

What the Vibe Code Rescue Scan checks

Every check has a stable, versioned code (e.g. RSC-SEC-014) and its own page: what is checked, why it matters and what to do. The catalogue is the open reference behind the score.

Scan your own app for free

How the score is calculated

The score is not an opinion, it is arithmetic. Here it is in full — so you can retrace any result and disagree with us. The numbers on this page come straight from the running code, not from documentation that can go stale.

Dimension weights

Security
0.26
Privacy (GDPR)
0.20
Scaling & cost
0.14
Accessibility
0.12
Architecture & SEO
0.16
Code quality
0.12

Deductions per finding

Every dimension starts at 100 points. Each finding deducts, depending on severity:

High
34
Medium
16
Low
7
Info
0

Deductions from “low” findings are capped at 21 points per dimension. Hygiene items should lower the score but never flip the verdict on their own — eight missing HTTP headers are not a broken foundation.

From score to verdict

  • From 75 points, and with no evidenced security or privacy finding: go — the visible signals look sound. A single medium-severity finding in either area turns this into “iterate” even at a high score: a green light next to a finding the same report lists would be a contradiction.
  • 45 to 74 points: iterate — solvable work, in a clear order.
  • Stop is issued only when at least one finding has severity “high” — an evidenced high-risk result such as an open database or an exposed master key. A low score alone is not enough.

Whatever could not be assessed is marked “limited” and never counts as perfect. A dimension without findings is 100 only if the required scan tier actually ran.

Methodology version 2026.09. Every substantive rule change increments it, so older results stay interpretable.

Security

RSC-SEC-001high

No end-to-end HTTPS

Checks whether the final response is served encrypted or ends up on plain http.

RSC-SEC-002medium

HSTS header missing

Checks whether Strict-Transport-Security is set so even the first request is protected.

RSC-SEC-003medium

No Content-Security-Policy

Checks header and meta tag for a Content-Security-Policy as the main XSS mitigation.

RSC-SEC-004low

MIME sniffing not disabled

Checks whether `X-Content-Type-Options: nosniff` stops content-type guessing.

RSC-SEC-005low

No clickjacking protection

Checks X-Frame-Options or CSP `frame-ancestors` against embedding in foreign pages.

RSC-SEC-006info

CORS wildcard on the public document

Records `Access-Control-Allow-Origin: *` on HTML — not a flaw by itself, but a signal to check.

RSC-SEC-007info

Server technology disclosed

Records version headers such as `X-Powered-By` that make targeted exploit search easier.

RSC-SEC-008medium

Cookies without Secure/HttpOnly

Checks issued cookies for the Secure and HttpOnly flags.

RSC-SEC-009info

Supabase client configuration visible

Records project URL and anon key in the bundle — expected, but the starting point for access checks.

RSC-SEC-010high

Supabase service_role key in the client

Decodes JWTs in the bundle and reports the `service_role` claim, which bypasses RLS entirely.

RSC-SEC-011high

Secret key in shipped code

Searches for real secret patterns (Stripe, AWS, GitHub, PEM) in HTML and bundles.

RSC-SEC-012info

Firebase backend detected

Records Firebase configuration in the client — allowed; what matters are the security rules.

RSC-SEC-013high

.env file publicly retrievable

Requests known env paths and confirms hits by KEY=VALUE line signatures.

RSC-SEC-014high

.git directory public

Confirms a shipped `.git` via the signatures of `config` and `HEAD`.

RSC-SEC-015medium

Database tables granted to the anon role

Queries the schema endpoint with the client key the app publishes itself and lists the tables granted to the anon role — without fetching a row or a row count. Granted is not the same as readable: whether rows come out depends on Row Level Security.

RSC-SEC-028high

Database tables anonymously readable (proven)

Answers the actual question: do rows really come out with the publicly shipped key? Counting happens purely via the `Content-Range` header of a HEAD request — not a single row is fetched.

RSC-SEC-029medium

Google API key in the client

Records keys in `AIza…` format in shipped code — expected for Maps and Firebase, risky without a domain restriction.

RSC-SEC-030high

Database credentials visible in the client

Finds connection strings with embedded username and password in HTML or bundles.

RSC-SEC-031high

Firestore collections anonymously readable

Queries the collections the app names in its own bundle using the public web key — with `mask.fieldPaths=__name__`, so document names only, not a single field value.

RSC-SEC-032medium

Database functions callable by anonymous users

Lists the RPC functions granted to the anon role, read from the schema description — read, never called.

RSC-SEC-033medium

Signup open, accounts confirmed instantly

Reads the anonymously available auth configuration: self-signup open and email confirmation disabled.

RSC-SEC-034high

AI API called directly from the browser (statically proven)

Finds AI provider endpoints in shipped code. `high` with a matching key pattern in the same bundle, `medium` without.

RSC-SEC-035medium

Browser writes directly to the database

Finds write calls (`insert`, `update`, `upsert`, `delete`, storage upload) in shipped code or in `use client` files.

RSC-SEC-036high

Credentials compared in browser code

Finds comparisons such as `password === "…"` against a fixed literal in shipped code.

RSC-SEC-016medium

Storage buckets publicly listable

Checks whether file buckets hand out their object listing anonymously.

RSC-SEC-017high

Firebase database anonymously readable

Queries the Realtime Database endpoint with `shallow=true`: if it returns key names instead of “permission denied”, the database is open.

RSC-SEC-018high

Protected area guarded only in the browser

Detects admin/account routes the client router knows while the guard lives purely as a condition in the bundle — anyone with the URL gets in.

RSC-SEC-019medium

Role check inside the client bundle

Finds role comparisons such as `role === "admin"` in shipped JavaScript — trivially manipulated in the browser.

RSC-SEC-020medium

Access token in localStorage

Observes at runtime whether a JWT-like value ends up in web storage — readable via XSS.

RSC-SEC-021high

AI API called directly from the browser

Observes calls to LLM providers from the client — the required key is exposed and any visitor can generate on your bill.

RSC-SEC-022high

Backup or database dump public

Probes typical dump/backup paths and confirms hits via SQL or archive signatures.

RSC-SEC-023info

No Permissions-Policy

Checks whether camera, microphone and geolocation are explicitly restricted by header.

RSC-SEC-024low

No Referrer-Policy

Checks whether outgoing links leak internal URLs including query strings to third parties.

RSC-SEC-025medium

Unencrypted assets on an HTTPS page

Finds scripts, stylesheets or images embedded via `http://` on an https page.

RSC-SEC-026medium

Sign-in without a detectable limit

After ownership proof, sends a small series of failing sign-in attempts and checks whether anything throttles.

RSC-SEC-027high

Admin area reachable anonymously

Requests discovered admin paths anonymously and reports content instead of a redirect to sign-in.

RSC-SEC-050high

Tables without Row Level Security

Collects every `create table` and every `enable row level security` across all migrations and reports tables that are never protected.

RSC-SEC-051high

RLS policy allows everyone

Finds policies with `using (true)` — RLS is on but has no effect.

RSC-SEC-066high

RLS policy checks only that someone is signed in

Finds policies using `auth.role() = 'authenticated'` or `auth.uid() is not null` without binding to the row owner.

RSC-SEC-067high

RLS policy allows arbitrary writes

Finds `with check (true)` — the read condition may be strict while writes stay wide open.

RSC-SEC-068high

Edge function without JWT verification

Finds `verify_jwt = false` in `supabase/config.toml` — the server function is callable without signing in.

RSC-SEC-069high

Firebase rules allow everyone

Finds `allow …: if true` in `.rules` files — Firestore or Storage is wide open.

RSC-SEC-052high

service_role key in source code

Decodes JWTs in source files and reports the `service_role` claim.

RSC-SEC-053high

Secret key in source code

Searches source files for real secret patterns (Stripe, AWS, OpenAI, Anthropic, Slack, SendGrid, PEM).

RSC-SEC-054high

Database credentials in plaintext

Finds connection strings with embedded username and password.

RSC-SEC-055high

.env file committed

Detects a `.env` with real values in the source tree (not `.env.example`).

RSC-SEC-056medium

Supabase in use, schema not versioned

Reports Supabase in the code without migrations containing tables and RLS — access control then cannot be verified from the code.

RSC-SEC-057high

Secret exposed via a public env prefix

Finds variables with a public bundler prefix (`NEXT_PUBLIC_`, `VITE_`, `REACT_APP_`, `PUBLIC_`, `EXPO_PUBLIC_` …) whose name implies a secret — such values are compiled into the client bundle.

RSC-SEC-063high

Env file inside the shipped bundle

Detects a `.env` with real values among the files reconstructed from source maps — the build shipped it.

RSC-SEC-058high

Server Action without an access check

Inspects the body of every `"use server"` function that writes to the database and reports a missing identity check — server actions are public endpoints.

RSC-SEC-080high

Dependencies with a known vulnerability

Matches the repository's package versions against the public OSV database and names the affected packages with advisory IDs.

RSC-SEC-081high

Secret key in the Git history

Checks the added lines of recent commits against the same pattern list as the current tree — a deleted key stays readable.

RSC-SEC-082medium

Env file was in the repository and got removed

Reports environment files present in the checked history but missing from the current tree — the old values stay retrievable.

RSC-SEC-070high

Signed-in strangers read other people's records

After domain verification, creates a throwaway account and counts how many rows that stranger sees in personal-data tables — without fetching a single row.

RSC-SEC-071medium

Table fully readable by any signed-in user

Reports tables hidden from anonymous callers but fully visible to a freshly created stranger account — intended for catalogue data, the same flaw otherwise.

RSC-SEC-072info

Tenant isolation holds under test

Confirms that a freshly created account with no data of its own saw no rows in the tables checked.

RSC-SEC-076high

A stranger's account can see your uploaded files

Uses a throwaway account to check whether non-public storage buckets can be listed.

RSC-SEC-077info

File storage sealed off from stranger accounts

The positive counterpart: no non-public bucket gave a stranger account a file listing.

RSC-SEC-074high

A stranger's account may write to your tables

Creates a throwaway account and checks per table whether it may write.

RSC-SEC-075info

Write access for stranger accounts rejected

The positive counterpart: the checked tables rejected every write attempt.

RSC-SEC-073info

Cross-tenant check could not run

Records that no account could be created (signup closed or confirmation required) — tenant isolation stays unverified.

RSC-SEC-064high

Access check runs after the write

Compares the position of the auth call and the database write within the same function body and reports checks that happen after the write.

RSC-SEC-065high

Auth result is never evaluated

Reports functions that look up the identity but neither check the result nor bind it to the write — the call has no effect.

RSC-SEC-059high

API route without an access check

Finds route handlers with mutating methods that contain no authentication.

RSC-SEC-060medium

Input reaching the database unvalidated

Traces request bodies that flow into an insert or update without schema validation (mass assignment).

RSC-SEC-061high

Webhook without signature verification

Detects payment webhooks that process the payload without verifying the signature — anyone could fake a payment.

RSC-SEC-062medium

Unsanitised HTML rendered

Finds `dangerouslySetInnerHTML` with a dynamic value — the classic XSS path.

Privacy (GDPR)

RSC-PRV-001medium

Google Fonts loaded at runtime

Finds references to fonts.googleapis.com/gstatic.com that send visitors' IP addresses to Google.

RSC-PRV-002medium

US tracking without visible consent

Detects analytics and pixel scripts with third-country transfer in the shipped markup.

RSC-PRV-003medium

Mandatory legal pages not visible

For German-language targets, checks whether imprint and privacy policy are linked.

RSC-PRV-004info

Privacy signals unremarkable

Standardised classification when no third-country transfers are visible from outside.

RSC-PRV-005high

Trackers fire before consent

Observes in the browser which third-party hosts are contacted on first load before anything was agreed to — the provable violation static checks can only suspect.

RSC-PRV-006medium

Data sent to third-country services

Lists foreign hosts contacted at runtime that typically process outside the EU.

RSC-PRV-007medium

Trackers without a consent layer

Reports consent-requiring scripts while no consent mechanism is detectable in the markup.

RSC-PRV-008high

Tracking cookies set before consent

Observes in the browser which cookies are set before any consent has been given.

RSC-PRV-009medium

Third-party cookies set before consent

Reports cookies from foreign domains that were set before any consent was given.

RSC-PRV-010medium

Consent without an equal reject option

Checks the rendered state for a reject option on the same level as the accept button.

RSC-PRV-016low

AI interaction without a visible notice

Finds AI endpoints in the client without a visible notice that users are interacting with an AI.

RSC-PRV-014low

Tracking cookie with a very long lifetime

Measures the lifetime of tracking cookies and reports anything beyond one year.

RSC-PRV-015medium

Consent with pre-ticked boxes

Finds already ticked checkboxes inside the consent interface.

RSC-PRV-011low

Imprint: mandatory details not found

Fetches the imprint page and looks for a postal address, a contact option and a register or VAT ID.

RSC-PRV-012low

Privacy policy: mandatory details not found

Fetches the privacy policy and looks for the controller, data subject rights, the right to complain and the retention period.

RSC-PRV-013low

Form without a privacy notice

Finds forms with an email field that have no reference to the privacy policy nearby.

Architecture & SEO

RSC-DET-001info

Platform detected

Detects the no-code/AI platform in use and weights its typical gaps.

RSC-DET-002info

Framework stack detected

Detects the framework stack for framework-native builds (Cursor, Claude Code, classic).

RSC-DET-003info

Domain ownership proven

Confirms a completed proof (DNS TXT or file) and unlocks the active checks.

RSC-DET-004info

Throwaway account created for the check

Names the account the scan created via your self-service signup to prove tenant isolation — so it stays deletable.

RSC-DET-005info

Test data could not be removed

Names records the write check created and could not delete again.

RSC-ARC-001medium

Content rendered client-side only

Detects empty root containers with almost no text in the initial HTML.

RSC-ARC-002low

Basic metadata missing

Checks page title and meta description in the document.

RSC-ARC-003low

Unchanged template title

Detects generator default titles such as “Vite + React” — a sign of unreviewed tool defaults.

RSC-ARC-004low

No canonical link

Checks whether the page declares a canonical URL (duplicate-content protection).

RSC-ARC-005medium

Non-existent paths answer with 200

Requests a random path: if the app serves content with status 200 there, neither browsers nor crawlers can detect errors.

RSC-ARC-006low

No robots.txt and no sitemap

Checks whether the target serves crawl directives and a sitemap.

RSC-ARC-007info

Very large document — partial assessment

Records that the HTML document exceeded the inspection limit and was only assessed up to that point. Not a defect, but a statement about coverage.