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 every verdict.

Scan your own app for free

How the verdict is derived

Until August 2026 this section held arithmetic: weighted dimensions, penalty points per finding, thresholds. It has been removed without replacement. A number built from freely chosen weights looked like a measurement but was an opinion with a decimal place — and it could hide an evidenced finding behind a good average. Three readable rules on severity and confidence take its place. The values on this page come straight from the running code, not from documentation that can go stale.

Severity — how bad it would be

Four levels. They state what the finding causes if it holds. Pure notices (“Supabase detected”) count internally as info and enter neither the list nor the verdict.

  • Criticalcritical
  • Highhigh
  • Mediummedium
  • Lowlow

Confidence — how sure we are

Derived from the tier that produced the finding. A missing header is beyond doubt from the outside; a guess from a partially reconstructed source map is not. Without this second value, observation and suspicion would sit side by side as equals:

  • confirmedconfirmed
  • highhigh
  • mediummedium

The three rules, per dimension

  1. Stop: at least one finding with severity “critical” AND confidence “confirmed”. Both together — “confirmed” only ever comes from a run with domain proof or repository access. This explicitly means: a purely anonymous external scan never says “stop”. It holds no finding it triggered itself or read in the source.
  2. Iterate: otherwise — at least one finding of “high” or above, or at least 3 findings of severity “medium” within the same dimension, or a single medium finding in security or privacy. A single medium finding is normal in an MVP; 3 in one area are a pattern. In the two areas that carry trust, however, one is enough: we cannot call a system “solid” next to an anonymously readable table or tracking without consent.
  3. Go: otherwise. Findings of severity “low” never flip the green light — eight missing HTTP headers are not a broken foundation. And two medium findings are exempt: “Content-Security-Policy missing” and “HSTS header missing” describe an absent extra layer of protection, not a defect. Not hardened is not the same as broken.

The overall verdict is the worst verdict across the six dimensions. Findings are not added up across areas: the threshold is meant to spot a pattern within ONE area. Findings a connected repository has dismissed no longer count.

Whatever could not be assessed is marked “limited” and shows “—”, never a zero and never a flattering top mark. Next to it stands the scan depth in numbers: how many checks applied in your case and how many of them actually ran. Checks that do not apply to you leave the denominator — checks we could not run stay in it.

Methodology version 2026.18. 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-010critical

Supabase service_role key in the client

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

RSC-SEC-011critical

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-013critical

.env file publicly retrievable

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

RSC-SEC-014critical

.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-028critical

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-030critical

Database credentials visible in the client

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

RSC-SEC-031critical

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-036critical

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-017critical

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-022critical

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-025high

Unencrypted assets on an HTTPS page (active / passive)

Finds resources embedded via `http://` on an https page and separates active ones (scripts, frames, stylesheets — blocked by the browser) from passive ones (images, audio, video — warning, no block).

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-084medium

No SPF and no DMARC — email spoofing unprotected

Checks whether the domain publishes at least an SPF or a DMARC record so receivers can recognise forged mail.

RSC-SEC-085medium

No DMARC record

Checks whether an existing SPF record is paired with a DMARC record that says what should happen to forged mail.

RSC-SEC-086high

SPF record with `+all`

Checks whether the SPF record ends in `+all` (or a bare `all`), which explicitly allows every server to send as the domain.

RSC-SEC-087low

DMARC with `p=none`

Checks whether the DMARC record is still at `p=none`, telling receivers to deliver forged mail anyway.

RSC-SEC-088info

No DKIM key found under common selectors

Queries a handful of common DKIM selectors and reports when none of them holds a key — a hint, not a finding of absence.

RSC-SEC-089high

TLS certificate expired

Reads the host's certificate and checks whether its validity date has passed.

RSC-SEC-090medium

TLS certificate about to expire

Reads the host's certificate and reports when it expires in 14 days or fewer.

RSC-SEC-091medium

Self-signed TLS certificate

Checks whether the served certificate is vouched for by its own subject instead of a public certificate authority.

RSC-SEC-092low

No CAA record

Checks whether the domain uses a CAA record to restrict which certificate authorities may issue certificates for it.

RSC-SEC-093low

No security.txt — no contact for vulnerability reports

Checks whether `/.well-known/security.txt` serves an RFC 9116 file with a contact line.

RSC-SEC-094low

security.txt without or with an expired Expires

Checks whether the existing security.txt carries the mandatory `Expires:` line and whether that date is still in the future.

RSC-SEC-095medium

package.json publicly accessible

Checks whether `/package.json` serves the project file with its name and dependency list.

RSC-SEC-096medium

API description (OpenAPI/Swagger) publicly accessible

Checks the usual paths (`/openapi.json`, `/swagger.json`, `/api-docs`, `/docs` …) for an OpenAPI/Swagger description or a Swagger UI / ReDoc page.

RSC-SEC-097medium

Third-party scripts without Subresource Integrity

Finds `<script src>` and `<link rel=stylesheet>` from public CDNs (cdnjs, jsDelivr, unpkg, jQuery, Bootstrap …) without an `integrity` attribute.

RSC-SEC-098critical

Database wide open (composite)

Combines what would be explainable in isolation: the access key in shipped code, missing or permissive Row Level Security and — for the critical tier — writes straight from the browser.

RSC-SEC-099high

Multiple secret families in the same build (composite)

Fires when at least two independent secrets (service-role key, database connection, credentials, provider keys, git history) were found in the same run.

RSC-SEC-100medium

Phishing-ready: mail spoofing plus login (composite)

Combines a domain without SPF/DMARC with a login or contact form on the site — the ingredients of a credible phishing mail in the domain's name.

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-051critical

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-067critical

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; on the syntax tree it also reports client files that read the key from the environment (comments do not count).

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-057critical

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-063critical

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-083medium

System prompt in the shipped code

Checks whether the instruction steering an AI assistant is shipped in the browser code.

RSC-SEC-078high

Shipped library with a known vulnerability

Detects front-end libraries and their version in the served bundle and in recovered source maps (retire.js signatures) and matches the version against OSV or the bundled retire.js database. Reports only on a confidently detected version.

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-070critical

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-076critical

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-074critical

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-062high

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-003high

Mandatory legal pages not visible

For targets with a German, Austrian or Swiss connection, 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-019low

Legal notice: sample values from the template

Checks whether the German legal notice still contains example values — sample address, placeholder email, unreplaced template fields.

RSC-PRV-020low

Testimonial with an invented face

Finds portraits from random-face generators inside sections that show testimonials or references.

RSC-PRV-021low

Generated media without a visible notice

For apps that generate images or audio, checks whether the visible text says anywhere that content comes from an AI.

RSC-PRV-022low

Contact data in the shipped JavaScript

Finds e-mail addresses and phone numbers in clear text inside the shipped JavaScript bundles — not in the HTML, where the legal notice requires them.

RSC-PRV-023medium

List of e-mail addresses public in the markup

Counts distinct e-mail addresses in the shipped HTML of the start page and the discovered sub-pages and reports from ten upwards — that looks like a publicly rendered member or customer list.

RSC-PRV-024low

CSP violations are reported to a third party

Reads `report-uri` and `report-to` from the Content Security Policy (header or meta tag) and reports when the reports go to a foreign host.

RSC-PRV-025high

Reject has no effect — trackers still load

Clicks the detected “reject” control of the consent banner in the browser and observes whether tracking services are still contacted or tracking cookies still set afterwards — the differential scan that makes an existing banner actually mean something.

RSC-PRV-026info

Reject works

Positive finding of the differential scan: after clicking “reject”, no tracking services were contacted and no tracking cookies were set.

RSC-PRV-018low

Images without an origin note

For apps that generate images, checks whether the invisible “made by an AI” note is still attached to what they serve.

RSC-PRV-017medium

Service not named in the privacy policy

Cross-checks the services your app actually contacts in the browser against the text of your privacy policy.

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 the identifier of the jurisdiction (VAT ID/commercial register, Firmenbuch/UID, CHE-UID/commercial register).

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.

RSC-PRV-027high

Consent theatre (composite)

Summarises the case where a banner with a reject option exists and consent-dependent services load anyway — before the decision or after clicking “reject”.

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-006info

Consent provider detected

Names the embedded consent management platform (Usercentrics, OneTrust, Cookiebot, Borlabs, …) — or that only Google's Consent Mode is present without a banner.

RSC-DET-007info

Services and routes of the app detected

Reads from the shipped JavaScript what the app talks to: own routes, backend services (Supabase, Firebase …), AI providers and other third-party services — as a list with method and location.

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-008low

Placeholder copy in the shipped state

Scans the visible text of the reached pages for dummy copy, sample details and unreplaced template fields.

RSC-ARC-009low

Mixed forms of address on one page

Counts the informal and formal German forms of address in a page's visible text and reports when two appear side by side.

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.

RSC-ARC-010info

Service worker detected

Detects a registered service worker (or one at `/sw.js` / `/service-worker.js`) and analyses its source like a bundle.

RSC-ARC-011info

Progressive web app detected

Detects a web app manifest linked via `<link rel="manifest">` that carries a name or start URL.

RSC-ARC-012low

Development address in shipped code

Finds calls to localhost, 127.0.0.1, private network addresses or tunnels (ngrok) in the shipped JavaScript — leftovers from development that go nowhere for users.