FixVibe

// docs / baas security / supabase service role exposure

Servisní klíč Supabase vystavený v JavaScriptu: co to znamená a jak ho najít

Servisní klíč Supabase je hlavní klíč k vaší databázi. Kdokoliv, kdo ho drží, obchází zabezpečení na úrovni řádků, může číst každý sloupec každé tabulky a může zapisovat nebo mazat cokoliv. Je navržen tak, aby žil výhradně v kódu na straně serveru — nikdy v prohlížeči. Když ho AI nástroj pro kódování pošle do JavaScript balíčku, vaše databáze je v podstatě veřejná. Tento článek vysvětluje tvar JWT, který identifikuje uniklý klíč, tři vzory AI nástrojů, které únik vyrábějí, co dělat v první hodině po detekci a jak na to automaticky skenovat dříve, než to udělají uživatelé.

Co je servisní klíč

Supabase vydává pro každý projekt dva odlišné klíče: klíč anon (v novějších projektech také nazývaný publishable klíč) a klíč service_role. Oba jsou JSON Web Tokeny podepsané JWT tajemstvím vašeho projektu. Rozdíl je v nároku role zapečeném v payloadu JWT — anon pro veřejný klíč, service_role pro hlavní klíč. PostgREST, Supabase Storage i Supabase Auth se přepnou do režimu obejít vše, jakmile uvidí nárok service_role.

Dekódujte jakýkoliv Supabase klíč na jwt.io a podívejte se na payload. Tvar JWT servisní role je nezaměnitelný:

Dekódovaný payload JWT servisní role (zobrazen jako blok se zvýrazněnou syntaxí níže).

json
{
  "iss": "supabase",
  "ref": "[project-ref]",
  "role": "service_role",
  "iat": 1700000000,
  "exp": 2000000000
}

Novější projekty Supabase vydávají klíče ve stylu tajemství s prefixem sb_secret_ místo JWT. Chování je shodné — cokoliv nesoucí sb_secret_ ve veřejném balíčku je stejně katastrofální.

Jak nástroje pro kódování s AI unášejí servisní klíč

Napříč tisíci vibe-kódovanými aplikacemi jsme viděli stejné tři vzory. Každý začíná tím, že vývojář žádá AI nástroj o pomoc, a končí tím, že je servisní klíč vložen přímo do balíčku.

Vzor 1: Jediný .env soubor s prefixem NEXT_PUBLIC_

Vývojář požádá AI nástroj, aby "nastavil Supabase", a přijme jeden .env s oběma klíči. AI nástroj — trénovaný na korpusu, kde je většina proměnných prostředí vystavena přes NEXT_PUBLIC_* — oběma předřadí NEXT_PUBLIC_. Next.js při sestavení vloží cokoliv odpovídajícího tomuto prefixu do klientského balíčku. Nasazení na Vercel a servisní klíč je v main.[hash].js.

Vzor 2: Špatný klíč ve volání createClient

Vývojář vloží oba klíče do souboru config.ts, který AI vygenerovalo, a AI omylem naplní volání createClient() na straně prohlížeče proměnnou process.env.SUPABASE_SERVICE_ROLE_KEY. Sestavení proměnnou natáhne a JWT skončí v balíčku.

Vzor 3: Servisní klíč napevno zapsán v seed skriptech

Vývojář požádá AI nástroj, aby napsal skript, který naplní databázi seedem. AI vepíše servisní klíč napevno přímo do souboru (místo čtení z prostředí), zacommituje soubor do repozitáře, a veřejný GitHub repozitář nebo cesta nasazené aplikace /scripts/seed.js nyní obsluhuje klíč.

Jak sken balíčku FixVibe detekuje únik

Kontrola bundle-secrets od FixVibe stáhne každý JavaScript soubor odkazovaný nasazenou aplikací — vstupní chunky, lazy-loaded chunky, web workery, service workery — a prožene je detektorem, který dekóduje cokoliv odpovídající tvaru JWT (eyJ[base64-header].eyJ[base64-payload].[signature]). Pokud dekódovaný payload obsahuje "role": "service_role", sken to nahlásí jako kritický nález s cestou souboru a přesným řádkem, kde se klíč objevuje. Stejná kontrola také porovnává novější vzor sb_secret_* podle prefixu.

Sken se nikdy neautentizuje objeveným klíčem. Identifikuje tvar a nahlásí únik — použít klíč k prokázání zneužitelnosti by bylo neoprávněným přístupem k vaší databázi. Důkaz je v samotném payloadu JWT.

Detekováno — co dělat v první hodině

Uniklý klíč servisní role je runtime nouzí. Předpokládejte, že klíč byl seškrábán — útočníci sledují veřejné balíčky v reálném čase. Považujte databázi za kompromitovanou, dokud klíč nerotujete a neprovedete audit nedávné aktivity.

  1. Okamžitě klíč rotujte. V Supabase Dashboardu jděte na Project Settings → API → Service role key → Reset. Starý klíč je během sekund invalidován. Jakýkoliv kód na straně serveru používající klíč musí být před tím, než rotace dorazí, aktualizován a znovu nasazen.
  2. Proveďte audit nedávné aktivity databáze. Otevřete v dashboardu Database → Logs. Filtrujte na posledních 7 dní. Hledejte neobvyklé dotazy SELECT * proti tabulkám s PII, velké příkazy UPDATE nebo DELETE a požadavky z IP adres mimo známou infrastrukturu. Supabase loguje hlavičku x-real-ip u každého požadavku.
  3. Zkontrolujte objekty úložiště. Navštivte Storage → Logs a projděte nedávná stažení souborů. Uniklý klíč servisní role dává přístup s obejitím všeho i k privátním košům.
  4. Odstraňte klíč ze správy zdrojového kódu. I po rotaci znamená ponechání JWT v git historii, že je objevitelný ve veřejném repozitáři. Použijte git filter-repo nebo BFG Repo-Cleaner k jeho vymazání z historie a pak vynuťte push (nejprve varujte kolaboranty).
  5. Naskenujte znovu po opravě. Spusťte čerstvý FixVibe sken proti znovu nasazené aplikaci. Nález bundle-secrets by měl zmizet. Potvrďte, že v žádném chunku nezůstal žádný service_role JWT ani řetězec sb_secret_*.

Předcházení úniku již na začátku

Strukturální opravou je pojmenovací disciplína plus ochranné mantinely na úrovni nástrojů:

  • Servisní klíč nikdy nepředřazujte prefixem NEXT_PUBLIC_*, VITE_* ani jakýmkoliv jiným prefixem vkládajícím do balíčku. Pojmenovací konvence je hranice — každý framework ji respektuje.
  • Udržujte servisní klíč zcela mimo .env na vývojářském stroji. Čtěte ho ze správce tajemství (Doppler, Infisical, šifrované env proměnné Vercel) při nasazení, nikdy ho lokálně necommitujte.
  • <strong>Mark every Supabase client construction with explicit context.</strong> Files named <code>supabase/browser.ts</code> use the anon key; files named <code>supabase/server.ts</code> use the service-role key with <code>import 'server-only'</code> at the top. The <code>server-only</code> import causes a build error if a client component tries to consume the module.
  • <strong>Add a pre-commit hook that greps for JWT-shaped strings.</strong> <code>git diff --staged | grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+'</code> catches both anon and service tokens before they leave your machine.
  • Přidejte CI bránu, která skenuje výstup sestavení. Po next build grepněte výstup .next/static/chunks/ na řetězec service_role. Pokud něco odpovídá, sestavení selže.
bash
# Pre-commit hook: refuse any staged JWT-shaped string.
git diff --staged \
  | grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+' \
  && echo "JWT detected in staged changes — refusing commit" \
  && exit 1

# CI gate: fail the build if "service_role" shipped to the static bundle.
grep -RE 'service_role|sb_secret_' .next/static/chunks/ \
  && echo "Service-role credential leaked into bundle" \
  && exit 1

Často kladené otázky

Jak rychle útočníci skutečně najdou uniklé klíče servisní role Supabase?

Skenery veřejných balíčků procházejí nová nasazení během minut. Výzkumníci dokumentovali funkční exploity proti novým projektům Supabase za méně než hodinu od prvního nasazení. Považujte jakékoliv vystavení servisní role za 60minutové okno, nikoliv 60denní.

Stačí rotace klíče, nebo musím předpokládat exfiltraci dat?

Rotace invaliduje uniklý klíč, ale nezruší již stažená data. Pokud vaše tabulky obsahují PII, platební údaje nebo jakákoliv regulovaná data, můžete mít notifikační povinnost podle GDPR (72 hodin), CCPA nebo HIPAA. Proveďte audit logů a poraďte se s právníkem, pokud audit ukáže podezřelý přístup.

Může mě RLS ochránit, když unikne klíč servisní role?

Ne. Zabezpečení na úrovni řádků je nárokem service_role zcela obcházeno. To je záměrné — klíč existuje právě proto, aby umožnil backendovému kódu přeskočit RLS pro administrativní operace. Mitigací je zajistit, aby se klíč nikdy nedostal do kontextu, kde by ho útočník mohl číst.

Platí to pro nový model publishable / secret klíčů Supabase (<code>sb_publishable_</code> / <code>sb_secret_</code>)?

Ano — identická riziková třída. Klíč sb_secret_* je nový formát tajného klíče, který v novějších projektech nahrazuje JWT servisní role. Cokoliv nesoucí sb_secret_* v balíčku je stejně katastrofální jako uniklý JWT servisní role. Detektor bundle-secrets od FixVibe porovnává oba tvary.

Co anon / publishable klíč — je v balíčku bezpečný?

Ano, záměrně. Anon klíč je určen, aby žil v prohlížeči, a používá ho každý webový klient Supabase. Jeho bezpečnost závisí zcela na tom, zda je RLS správně nakonfigurováno na každé veřejné tabulce. Co kontrolovat, viz článek Skener Supabase RLS.

Další kroky

Spusťte FixVibe sken proti vaší produkční URL — kontrola bundle-secrets je zdarma, bez registrace a hlásí vystavení service_role za méně než minutu. Spárujte to s článkem Skener Supabase RLS pro ověření, že vrstva RLS dělá svou práci, a Kontrolní seznam zabezpečení úložného koše Supabase pro uzamčení přístupu k souborům. Pro pozadí toho, proč AI nástroje generují tuto třídu úniku tak spolehlivě, si přečtěte Proč nástroje pro kódování s AI nechávají bezpečnostní mezery.

// naskenujte svůj baas povrch

Najděte otevřenou tabulku dříve, než to udělá někdo jiný.

Zadejte produkční URL. FixVibe vyjmenuje poskytovatele BaaS, se kterými vaše aplikace komunikuje, sejme otisky jejich veřejných koncových bodů a nahlásí, co může neověřený klient číst nebo zapisovat. Zdarma, bez instalace, bez karty.

  • Bezplatná úroveň — 3 skeny / měsíc, bez karty při registraci.
  • Pasivní snímání otisků BaaS — bez nutnosti ověření domény.
  • Supabase, Firebase, Clerk, Auth0, Appwrite a další.
  • AI návrhy oprav u každého nálezu — vložte zpět do Cursor / Claude Code.
Spustit bezplatný sken BaaS

registrace není potřeba

Servisní klíč Supabase vystavený v JavaScriptu: co to znamená a jak ho najít — Docs · FixVibe