// docs / baas security / supabase service role exposure
A Supabase service role kulcs JavaScriptben felfedve: mit jelent és hogyan találd meg
A Supabase service role kulcs az adatbázisod főkulcsa. Aki birtokolja, megkerüli a row-level securityt, minden tábla minden oszlopát képes olvasni, és bármit írhat vagy törölhet. Úgy van tervezve, hogy kizárólag szerveroldali kódban éljen — soha ne böngészőben. Amikor egy MI-kódoló eszköz a JavaScript-bundle-be juttatja, az adatbázisod gyakorlatilag nyilvános. Ez a cikk elmagyarázza a kiszivárgott kulcsot azonosító JWT-formát, a szivárgást előállító három MI-eszköz-mintát, mit tegyél a detektálást követő első órában, és hogyan szkennelj erre automatikusan, mielőtt a felhasználók tennék.
Mi a service role kulcs
A Supabase két különböző kulcsot ad ki minden projekthez: az anon kulcsot (újabb projektekben publishable kulcsnak is nevezik) és a service_role kulcsot. Mindkettő JSON Web Token, a projekted JWT-titkával aláírva. A különbség a JWT payloadba sütött role claim — anon a nyilvános kulcsnak, service_role a főkulcsnak. A PostgREST, a Supabase Storage és a Supabase Auth mind mindent-megkerülő módra váltanak, ha látják a service_role claimet.
Dekódolj bármilyen Supabase-kulcsot a jwt.io-n, és nézd meg a payloadot. Egy service-role JWT formája félreismerhetetlen:
Egy service-role JWT dekódolt payloadja (alább szintaxiskiemelt blokkként megjelenítve).
{
"iss": "supabase",
"ref": "[project-ref]",
"role": "service_role",
"iat": 1700000000,
"exp": 2000000000
}Az újabb Supabase-projektek secret-stílusú kulcsokat adnak ki sb_secret_ előtaggal JWT helyett. A viselkedés azonos — bármi, ami sb_secret_-et tartalmaz egy nyilvános bundle-ben, ugyanolyan katasztrofális.
Hogyan szivárogtatják az MI-kódoló eszközök a service role kulcsot
Több ezer vibe-kódolt alkalmazáson keresztül ugyanazt a három mintát láttuk. Mindegyik azzal kezdődik, hogy egy fejlesztő egy MI-eszközt kér segítségül, és azzal végződik, hogy a service kulcs egy bundle-be ágyazódik.
Minta 1: Egyetlen .env fájl NEXT_PUBLIC_ előtaggal
A fejlesztő megkéri az MI-eszközt, hogy „állítsa be a Supabase-t", és elfogad egy egyetlen .env-et mindkét kulccsal. Az MI-eszköz — egy olyan korpuszon tanítva, ahol a legtöbb környezeti változó NEXT_PUBLIC_*-on keresztül van kitéve — mindkettőt NEXT_PUBLIC_-kel prefixeli. A Next.js mindent, ami illeszkedik erre az előtagra, build időben beágyaz a kliensbundle-be. Deploy a Vercelre, és a service kulcs a main.[hash].js-ben van.
Minta 2: Rossz kulcs a createClient hívásban
A fejlesztő beilleszti mindkét kulcsot egy config.ts fájlba, amit az MI generált, és az MI tévedésből a böngésző oldali createClient() hívást a process.env.SUPABASE_SERVICE_ROLE_KEY-vel tölti fel. A build behúzza a változót, és a JWT a bundle-be kerül.
Minta 3: Service-role kulcs hardcode-olva a seed szkriptekbe
A fejlesztő megkéri az MI-eszközt, hogy írjon egy szkriptet, ami feltölti az adatbázist. Az MI a service-role kulcsot közvetlenül a fájlba hardcode-olja (ahelyett, hogy környezetből olvasná), commitolja a fájlt a repóba, és a nyilvános GitHub-repó vagy a deployolt alkalmazás /scripts/seed.js útvonala most már kiszolgálja a kulcsot.
Hogyan detektálja a FixVibe bundle-szkennelés a szivárgást
A FixVibe bundle-secrets ellenőrzése letölt minden JavaScript-fájlt, amelyre a deployolt alkalmazás hivatkozik — entry chunkok, lazy-betöltött chunkok, web workerek, service workerek —, és átfuttatja őket egy detektoron, ami mindent dekódol, ami JWT-formára illeszkedik (eyJ[base64-header].eyJ[base64-payload].[signature]). Ha a dekódolt payload tartalmazza a "role": "service_role"-t, a szkennelés kritikus találatként jelenti, fájlútvonallal és a kulcs pontos sorával. Ugyanez az ellenőrzés az újabb sb_secret_* mintára is illeszkedik előtag alapján.
A szkennelés soha nem hitelesít magát a felfedezett kulccsal. Azonosítja a formát és jelenti a szivárgást — a kulcs használata a kihasználhatóság bizonyítására jogosulatlan hozzáférés lenne az adatbázisodhoz. A bizonyíték magában a JWT payloadban van.
Detektálva — mit tegyél az első órában
Egy kiszivárgott service role kulcs futási idejű vészhelyzet. Feltételezd, hogy a kulcsot kinyerték — a támadók valós időben figyelik a nyilvános bundle-eket. Kezeld az adatbázist kompromittáltként, amíg nem rotáltad a kulcsot és nem auditáltad a közelmúlt tevékenységét.
- Rotáld a kulcsot azonnal. A Supabase Dashboardon menj a Project Settings → API → Service role key → Reset menüpontra. A régi kulcs másodperceken belül érvénytelenné válik. Bármely szerveroldali kód, ami használja a kulcsot, frissítendő és újradeployolandó, mielőtt a rotáció érvénybe lép.
- Auditáld a közelmúlt adatbázis-tevékenységét. Nyisd meg a Database → Logs menüpontot a dashboardon. Szűrj az utolsó 7 napra. Keress szokatlan
SELECT *lekérdezéseket PII-t tartalmazó táblákon, nagyUPDATEvagyDELETEutasításokat és kéréseket az ismert infrastruktúrádon kívüli IP-ktől. A Supabase azx-real-ipfejlécet minden kérésnél naplózza. - Ellenőrizd a storage objektumokat. Látogasd meg a Storage → Logs menüpontot, és tekintsd át a közelmúlt fájl-letöltéseit. Egy kiszivárgott service-role kulcs mindent-megkerülő hozzáférést ad a privát bucketökhöz is.
- Távolítsd el a kulcsot a verziókezelésből. A rotáció után is, ha a JWT a git-történetedben marad, az a nyilvános repóban felfedezhető. Használj
git filter-repo-t vagy BFG Repo-Cleanert, hogy kiszedd a történetből, majd force-push (figyelmeztesd előbb a közreműködőket). - Szkennelj újra a fix után. Futtass egy friss FixVibe-szkennelést az újradeployolt alkalmazásra. A bundle-secrets találatnak el kell tűnnie. Erősítsd meg, hogy nincs többé
service_roleJWT éssb_secret_*string egyetlen chunkban sem.
A szivárgás megakadályozása előre
A strukturális javítás névfegyelem plusz eszközszintű korlátok:
- Soha ne prefixeld a service kulcsot
NEXT_PUBLIC_*,VITE_*vagy bármilyen más bundle-beágyazó előtaggal. A névadási konvenció a határ — minden framework tiszteli. - Tartsd a service kulcsot teljesen kívül a
.env-en a fejlesztői gépen. Olvasd ki egy secret-managerből (Doppler, Infisical, Vercel titkosított env változók) deploy idején, soha ne commitold lokálisan. - <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.
- Adj hozzá egy CI-kaput, ami a build kimenetét szkenneli. A
next buildután grepeld a.next/static/chunks/kimenetet aservice_rolestringre. Buktasd el a buildet, ha bármi illeszkedik.
# 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 1Gyakori kérdések
Milyen gyorsan találják meg a támadók valójában a kiszivárgott Supabase service-role kulcsokat?
A nyilvános bundle-szkennerek percek alatt átfésülik az új deploymenteket. Kutatók dokumentáltak működő exploitokat új Supabase-projektek ellen egy órán belül az első deploy után. Kezelj minden service-role-kitettséget 60 perces ablakként, ne 60 naposként.
Elég a kulcs rotálása, vagy fel kell tételeznem az adatkiszivárgást?
A rotáció érvényteleníti a kiszivárgott kulcsot, de nem teszi vissza a már lehúzott adatokat. Ha a tábláid PII-t, fizetési adatokat vagy bármilyen szabályozott adatot tartalmaznak, lehet, hogy GDPR (72 óra), CCPA vagy HIPAA szerinti értesítési kötelezettséged van. Auditáld a logokat, és konzultálj jogi tanácsadóval, ha az audit gyanús hozzáférést mutat.
Megvédhet az RLS, ha a service-role kulcs kiszivárog?
Nem. A row-level securityt teljesen megkerüli a service_role claim. Ez tervezésből van — a kulcs pontosan azért létezik, hogy a backend kód kihagyhassa az RLS-t admin műveletekhez. A mitigáció az, hogy a kulcs soha ne érjen el olyan kontextust, ahol egy támadó olvashatja.
Vonatkozik ez az új Supabase publishable / secret kulcs modellre (<code>sb_publishable_</code> / <code>sb_secret_</code>)?
Igen — azonos kockázati osztály. Az sb_secret_* kulcs az új secret-kulcs-formátum, ami az újabb projektekben a service-role JWT-t váltja. Bármi, ami sb_secret_*-ot hordoz egy bundle-ben, ugyanolyan katasztrofális, mint egy kiszivárgott service-role JWT. A FixVibe bundle-secrets detektora mindkét formát illeszti.
És az anon / publishable kulcs — az biztonságos a bundle-ben?
Igen, tervezésből. Az anon kulcs arra van szánva, hogy a böngészőben éljen, és minden Supabase webkliens ezt használja. A biztonsága teljes egészében attól függ, hogy az RLS helyesen van-e konfigurálva minden nyilvános táblán. Lásd a Supabase RLS-szkenner cikket, hogy mit kell ellenőrizni.
Következő lépések
Futtass egy FixVibe-szkennelést az éles URL-edre — a bundle-secrets ellenőrzés ingyenes, regisztráció nélküli, és egy percnél is rövidebb idő alatt jelenti a service_role kitettséget. Párosítsd ezt a Supabase RLS-szkenner cikkel, hogy ellenőrizd, az RLS-réteg végzi-e a dolgát, és a Supabase storage bucket biztonsági checklist cikkel a fájlhozzáférés zárolásához. Háttérinformációért arról, hogy az MI-eszközök miért generálják ennyire megbízhatóan ezt a szivárgási osztályt, olvasd el Miért hagynak biztonsági réseket az MI-kódoló eszközök.
