// docs / baas security / supabase service role exposure
Chjave di service-role Supabase esposta in JavaScript: ciò chì significa è cumu trovala
A chjave di service-role Supabase hè a chjave maestra di a to basa di dati. Chìunque l'abbia passa sopra à a sicurezza à livellu di riga, pò leghje ogni colonna di ogni tabella è pò scrive o sguassà qualunque cosa li piaci. Hè cuncepita per vive esclusivamente in u codice latu servitore — mai in u navigatore. Quandu un attrezzu di codifica IA a manda in u bundle JavaScript, a to basa di dati hè, in fatti, pubblica. St'articulu spiega a forma JWT chì identifica una chjave persa, i trè pattern di l'attrezzi IA chì producenu a perdita, ciò chì fà in a prima ora dopu a rilevazione, è cumu scanà automaticamente prima di l'utenti.
Ciò chì hè a chjave di service-role
Supabase emette duie chjavi distinte per ogni prughjettu: a chjave anon (ancu chjamata chjave publishable in i prughjetti più recenti) è a chjave service_role. Tramendue sò JSON Web Token firmati da u secretu JWT di u to prughjettu. A sfarenza hè u claim role incurpuratu in u payload di u JWT — anon per a chjave pubblica, service_role per a chjave maestra. PostgREST, Supabase Storage è Supabase Auth tutti passanu in modu di bypassà-tuttu quandu vedenu u claim service_role.
Deccoddifica qualunque chjave Supabase à jwt.io è guarda u payload. A forma di un JWT di service-role hè inconfondibile:
Payload decuddificatu di un JWT di service-role (mustratu cum'è un bloccu evidenziatu sottu).
{
"iss": "supabase",
"ref": "[project-ref]",
"role": "service_role",
"iat": 1700000000,
"exp": 2000000000
}I prughjetti Supabase più recenti emettenu chjavi di tippu secretu cù u prefissu sb_secret_ invece di un JWT. U cumpurtamentu hè identicu — qualunque cosa chì porta sb_secret_ in un bundle pubblicu hè ugualmente catastrofica.
Cumu l'attrezzi di codifica IA fannu perde a chjave di service-role
Avemu vistu listessi trè pattern trà mille di app vibe-coded. Ognunu principia cù un sviluppatore chì dumanda aiutu à un attrezzu IA è finisce cù a chjave di serviziu inline in un bundle.
Pattern 1: schedariu .env unicu cù prefissu NEXT_PUBLIC_
U sviluppatore dumanda à l'attrezzu IA di "cunfigurà Supabase" è accetta un sulu .env cù e duie chjavi. L'attrezzu IA — addestratu nantu à un corpus duve a maiò parte di e variabbili d'ambiente sò esposte via NEXT_PUBLIC_* — prefissa tramendue cù NEXT_PUBLIC_. Next.js incorpora qualunque cosa chì currisponde à quellu prefissu in u bundle cliente à u mumentu di a build. Manda à Vercel, è a chjave di serviziu hè in main.[hash].js.
Pattern 2: chjave sbagliata in a chjamata createClient
U sviluppatore incolla e duie chjavi in un schedariu config.ts generatu da l'IA, è l'IA pupula a chjamata createClient() latu navigatore cù process.env.SUPABASE_SERVICE_ROLE_KEY per sbagliu. A build tira a variabbile, è u JWT atterra in u bundle.
Pattern 3: chjave service-role hardcoded in scripts di seed
U sviluppatore dumanda à l'attrezzu IA di scrive un scrittu chì pupula a basa di dati. L'IA hardcoda a chjave di service-role direttamente in u schedariu (invece di leghje da l'ambiente), committa u schedariu in u repositoriu, è u repo publicu GitHub o u percorsu /scripts/seed.js di l'app spiegata serve avà a chjave.
Cumu u scan di bundle FixVibe piglia a perdita
U check bundle-secrets di FixVibe scarica ogni schedariu JavaScript riferitu da l'app spiegata — chunk d'entrata, chunk lazy-loaded, web worker, service worker — è i passa per un rilevatore chì decuddifica qualunque cosa chì currisponde à a forma JWT (eyJ[base64-header].eyJ[base64-payload].[signature]). S'è u payload decuddificatu cuntene "role": "service_role", a scansione u sgnala cum'è un risultatu criticu cù u percorsu di u schedariu è a linea esatta duve apparisce a chjave. Listessu check ancu matcheghja u pattern più recente sb_secret_* per prefissu.
A scansione ùn s'autentica mai cù a chjave scuperta. Identifica a forma è sgnala a perdita — adoprà a chjave per pruvà l'exploitability seria accessu micca autorizatu à a to basa di dati. A prova hè in u payload JWT stessu.
Rilevata — ciò chì fà in a prima ora
Una chjave di service-role persa hè una emergenza in runtime. Suppone chì a chjave hè stata raccolta — l'attaccanti monitoreghjanu i bundle pubblichi in tempu reale. Tratta a basa di dati cum'è compromessa finu chì ùn averai ruttatu a chjave è auditatu l'attività recente.
- Rutteghja a chjave immediatamente. In u Supabase Dashboard, vai à Project Settings → API → Service role key → Reset. A vechja chjave hè invalidata in secondi. Ogni codice latu serviziu chì usa a chjave deve esse aghjurnatu è ri-spiegatu prima chì a rotazione si applichi.
- Auditeghja l'attività recente di a basa di dati. Apri Database → Logs in u dashboard. Filtra nantu à l'ultimi 7 ghjorni. Cerca query
SELECT *insolite contru à tabelle cù PII, istruzzioniUPDATEoDELETEgrandi, è richieste da IP fora di a to infrastruttura cunnisciuta. Supabase registra l'headerx-real-ipin ogni richiesta. - Verifica l'ughjetti di storage. Visita Storage → Logs è rivedi i scaricamenti recenti di schedarii. Una chjave di service-role persa dà ancu accessu bypassà-tuttu à i bucket privati.
- Caccia a chjave da u cuntrollu di fonte. Ancu dopu a rotazione, lascià u JWT in a to storia git significa ch'ellu hè scopribile in u repo publicu. Adopra
git filter-repoo BFG Repo-Cleaner per cacciallu da a storia, dopu force-push (avverte prima i collaboratori). - Riscaneghja dopu a currezzione. Lampa una nova scansione FixVibe contru à l'app ri-spiegata. U risultatu bundle-secrets deve sparisce. Cunferma chì nisun JWT
service_roleè nesuna stringasb_secret_*ferma in nisun chunk.
Prevene a perdita dapoi u principiu
A currezzione strutturale hè disciplina di nomenclatura più garde di prutezzione à livellu di attrezzu:
- Mai prefissà a chjave di serviziu cù
NEXT_PUBLIC_*,VITE_*o qualunque altru prefissu di inlining in u bundle. A cunvenzione di nomenclatura hè a fruntiera — ogni framework a rispetta. - Tene a chjave di serviziu fora di
.envà u tuttu nantu à a macchina di u sviluppatore. Leghjela da un gestore di secreti (Doppler, Infisical, variabbili d'ambiente cifrate Vercel) à u spiegamentu, mai committalla in lucale. - <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.
- Aghjusta una porta CI chì scansiuneghja l'output di a build. Dopu
next build, grepa l'output.next/static/chunks/per a stringaservice_role. Falla a build s'è qualcosa currisponde.
# 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 1Dumande frequenti
Quantu prestu l'attaccanti trovanu veramente e chjavi service-role Supabase perse?
I scanner di bundle publichi trecculanu i novi spiegamenti in minuti. I ricercatori anu documentatu exploit funziunanti contru à novi prughjetti Supabase in menu d'una ora dapoi u primu spiegamentu. Tratta qualunque esposizione di service-role cum'è una finestra di 60 minuti, micca una di 60 ghjorni.
Rutà a chjave hè abbastanza, o devu suppone exfiltrazione di dati?
A rotazione invalideghja a chjave persa ma ùn annulla micca i dati digià tirati. S'è e to tabelle cuntenenu PII, dati di pagamentu, o qualunque datu regulatu, pudè avè una obbligazione di notifica sottu à GDPR (72 ore), CCPA, o HIPAA. Auditeghja i log è cunsulta cunsigliu legale s'è l'audit mostra accessu suspettu.
RLS pò prutege se a chjave di service-role perde?
Nò. A sicurezza à livellu di riga hè cumpletamente passata sopra da u claim service_role. Hè per disegnu — a chjave esiste propiu per lascià u codice backend salta RLS per operazioni amministrative. A mitigazione hè di assicurassi chì a chjave ùn ghjunghji mai in un cuntestu duve un attaccante pò leghjela.
Hè applicà à u novu mudellu di chjave publishable / secretu Supabase (<code>sb_publishable_</code> / <code>sb_secret_</code>)?
Iè — classa di risicu identica. A chjave sb_secret_* hè u novu furmatu di chjave secreta chì rimpiazza u JWT di service-role per i prughjetti più recenti. Qualunque cosa chì porta sb_secret_* in un bundle hè altrettantu catastroficu quant'è un JWT di service-role persu. U rilevatore bundle-secrets di FixVibe matcheghja e duie forme.
Chì face a chjave anon / publishable — hè sicura in u bundle?
Iè, per disegnu. A chjave anon hè destinata à vive in u navigatore è hè ciò chì ogni cliente web Supabase usa. A so sicurezza dipende cumpletamente da RLS chì hè currettamente cunfiguratu nantu à ogni tabella pubblica. Vedi l'articulu Scanner RLS Supabase per ciò chì cuntrullà.
Prussimi passi
Lampa una scansione FixVibe contru à u to URL di produzzione — u check bundle-secrets hè gratisi, senza iscrizzione, è riporta l'esposizione service_role in menu d'un minutu. Accuppia questu cù l'articulu Scanner RLS Supabase per verificà chì u stratu RLS sta facendu u so travagliu, è a Lista di cuntrollu di sicurezza di bucket Supabase Storage per chjude l'accessu à i schedarii. Per u sfondu nantu à perchè l'attrezzi IA generanu sta classa di perdita cù tantu affidabilità, leghji Perchè l'attrezzi di codifica IA lascianu falle di sicurezza.
