FixVibe

// docs / baas security / supabase service role exposure

Supabase service role key na naka-expose sa JavaScript: ano ang ibig sabihin nito at paano ito hanapin

Ang Supabase service role key ay ang master key sa iyong database. Sinumang humahawak nito ay nakaka-bypass sa Row-Level Security, makakabasa ng bawat column ng bawat talahanayan, at makakapagsulat o makakapagtanggal ng kahit ano. Idinisenyo itong tumira lamang sa server-side na code โ€” hindi kailanman sa browser. Kapag ipinadala ito ng AI coding tool sa JavaScript bundle, ang iyong database ay, sa katotohanan, pampubliko. Ipinapaliwanag ng artikulong ito ang hugis ng JWT na nagpapakilala sa isang na-leak na key, ang tatlong patterns ng AI tool na gumagawa ng leak, ano ang gagawin sa unang oras matapos ang deteksyon, at kung paano ito i-scan nang awtomatiko bago pa magawa ng mga gumagamit.

Ano ang service role key

Naglalabas ang Supabase ng dalawang magkaibang keys para sa bawat project: ang anon key (tinatawag ding publishable key sa mas bagong mga project) at ang service_role key. Pareho silang JSON Web Tokens na pinirmahan ng JWT secret ng iyong project. Ang pagkakaiba ay ang role claim na nakapaloob sa JWT payload โ€” anon para sa public key, service_role para sa master key. Ang PostgREST, Supabase Storage, at Supabase Auth ay lahat lumilipat sa bypass-everything mode kapag nakita nila ang service_role claim.

I-decode ang anumang Supabase key sa jwt.io at tingnan ang payload. Hindi maipagkakamali ang hugis ng service-role JWT:

Naka-decode na payload ng service-role JWT (ipinapakita bilang isang syntax-highlighted block sa ibaba).

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

Naglalabas ang mas bagong mga Supabase project ng secret-style keys na may prefix na sb_secret_ sa halip na JWT. Pareho ang behavior โ€” anumang nagdadala ng sb_secret_ sa isang pampublikong bundle ay pantay na katastropiko.

Paano nag-le-leak ng service role key ang AI coding tools

Nakita namin ang parehong tatlong patterns sa libu-libong vibe-coded apps. Ang bawat isa ay nagsisimula sa isang developer na humihingi ng tulong sa isang AI tool at nagtatapos sa service key na naka-inline sa isang bundle.

Pattern 1: Iisang .env file na may NEXT_PUBLIC_ prefix

Hinihiling ng developer sa AI tool na "i-set up ang Supabase" at tinatanggap ang isang .env na may parehong keys. Ang AI tool โ€” na sinanay sa isang corpus kung saan karamihan ng environment variables ay ina-expose sa pamamagitan ng NEXT_PUBLIC_* โ€” ay nilalagyan ng NEXT_PUBLIC_ prefix ang dalawa. Ina-inline ng Next.js ang anumang katugma sa prefix na iyon sa client bundle sa build time. I-deploy sa Vercel, at ang service key ay nasa main.[hash].js.

Pattern 2: Maling key sa createClient call

Ipini-paste ng developer ang parehong keys sa isang config.ts file na ginawa ng AI, at pinupunan ng AI ang browser-side na createClient() call ng process.env.SUPABASE_SERVICE_ROLE_KEY nang nagkakamali. Hinihila ng build ang variable, at lumalapag ang JWT sa bundle.

Pattern 3: Service-role key na naka-hardcode sa seed scripts

Hinihiling ng developer sa AI tool na sumulat ng script na nag-se-seed ng database. Ni-ha-hardcode ng AI ang service-role key nang direkta sa file (sa halip na basahin mula sa environment), kino-commit ang file sa repository, at ang pampublikong GitHub repo o ang /scripts/seed.js route ng naka-deploy na app ay nagse-serve na ng key.

Paano nade-detect ng FixVibe bundle scan ang leak

Ang bundle-secrets check ng FixVibe ay nagda-download ng bawat JavaScript file na ginagamit ng naka-deploy na app โ€” entry chunks, lazy-loaded chunks, web workers, service workers โ€” at pinapatakbo sila sa isang detector na nagde-decode ng anumang katugma sa JWT shape (eyJ[base64-header].eyJ[base64-payload].[signature]). Kung ang na-decode na payload ay naglalaman ng "role": "service_role", iniuulat ng scan ito bilang critical finding na may file path at ang eksaktong linya kung saan lumitaw ang key. Ang parehong check ay nagma-match din sa mas bagong sb_secret_* pattern sa pamamagitan ng prefix.

Ang scan ay hindi kailanman nag-a-authenticate gamit ang natuklasang key. Tinutukoy nito ang hugis at iniuulat ang leak โ€” ang paggamit ng key upang patunayan ang exploitability ay magiging unauthorized access sa iyong database. Ang patunay ay nasa JWT payload mismo.

Natuklasan โ€” ano ang gagawin sa unang oras

Ang isang na-leak na service role key ay isang runtime emergency. Ipalagay na na-scrape na ang key โ€” minomonitor ng mga umaatake ang mga pampublikong bundle sa real time. Ituring ang database bilang kompromisado hanggang sa naipalit mo ang key at na-audit mo na ang kamakailang aktibidad.

  1. I-rotate ang key kaagad. Sa Supabase Dashboard, pumunta sa Project Settings โ†’ API โ†’ Service role key โ†’ Reset. Ang lumang key ay na-invalidate sa ilang segundo. Anumang service-side code na gumagamit ng key ay kailangang maupdate at maideploy muli bago lumapag ang rotation.
  2. I-audit ang kamakailang database activity. Buksan ang Database โ†’ Logs sa dashboard. I-filter sa huling 7 araw. Maghanap ng mga hindi karaniwang SELECT * queries laban sa mga talahanayan na may PII, malalaking UPDATE o DELETE statements, at mga request mula sa mga IP na hindi mo kilala bilang iyong infrastructure. Itinatala ng Supabase ang x-real-ip header sa bawat request.
  3. Tingnan ang mga storage objects. Bisitahin ang Storage โ†’ Logs at suriin ang mga kamakailang file downloads. Ang isang na-leak na service-role key ay nagbibigay ng bypass-everything access sa mga private bucket din.
  4. Alisin ang key sa source control. Kahit pagkatapos ng rotation, ang pag-iwan sa JWT sa iyong git history ay nangangahulugang matatagpuan ito sa pampublikong repo. Gamitin ang git filter-repo o BFG Repo-Cleaner upang burahin ito sa history, pagkatapos force-push (balaan muna ang mga collaborator).
  5. I-scan muli pagkatapos ng pag-aayos. Magpatakbo ng bagong FixVibe scan laban sa muling-deploy na app. Dapat nang mawala ang bundle-secrets finding. Kumpirmahin na walang natitirang service_role JWT at walang sb_secret_* string sa anumang chunk.

Pag-iwas sa leak sa unang lugar

Ang structural fix ay disiplina sa pagngangalan kasama ng mga tool-level guardrails:

  • Huwag kailanman lagyan ng prefix ang service key ng NEXT_PUBLIC_*, VITE_*, o anumang ibang bundle-inlining prefix. Ang naming convention ang hangganan โ€” iginagalang ito ng bawat framework.
  • Panatilihin ang service key sa labas ng .env nang buo sa makina ng developer. Basahin ito mula sa isang secret manager (Doppler, Infisical, Vercel encrypted env vars) sa deploy, huwag kailanman i-commit lokal.
  • <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.
  • Magdagdag ng CI gate na nag-iiscan ng build output. Pagkatapos ng next build, i-grep ang .next/static/chunks/ output para sa service_role string. Pabaguhin ang build kung may anumang tumugma.
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

Mga madalas na itinatanong

Gaano kabilis aktwal na nahahanap ng mga umaatake ang mga na-leak na Supabase service-role keys?

Ang mga public-bundle scanners ay nagha-harvest ng mga bagong deployments sa loob ng ilang minuto. Itinala ng mga researchers ang mga gumaganang exploits laban sa mga bagong Supabase project sa wala pang isang oras mula sa unang deploy. Ituring ang anumang service-role exposure bilang 60-minute window, hindi 60-day.

Sapat na ba ang pag-rotate ng key, o kailangan kong ipalagay na may na-exfiltrate na data?

Ina-invalidate ng rotation ang na-leak na key ngunit hindi binubura ang datos na nakuha na. Kung naglalaman ang iyong mga talahanayan ng PII, payment data, o anumang regulated na data, maaari kang may obligasyon sa notipikasyon sa ilalim ng GDPR (72 oras), CCPA, o HIPAA. I-audit ang logs at kumonsulta sa legal counsel kung nagpapakita ang audit ng kahina-hinalang access.

Mapoprotektahan ba ako ng RLS kung mag-leak ang service-role key?

Hindi. Ang Row-Level Security ay buong-buong na-bypass ng service_role claim. Iyon ay sa disenyo โ€” umiral ang key partikular upang payagan ang backend code na laktawan ang RLS para sa mga admin operations. Ang mitigation ay tiyakin na ang key ay hindi kailanman umabot sa isang konteksto kung saan mababasa ito ng umaatake.

Aplikable ba ito sa bagong Supabase publishable / secret key model (<code>sb_publishable_</code> / <code>sb_secret_</code>)?

Oo โ€” magkapareho ang risk class. Ang sb_secret_* key ay ang bagong secret-key format na pumapalit sa service-role JWT para sa mga mas bagong project. Anumang nagdadala ng sb_secret_* sa isang bundle ay pantay na katastropiko gaya ng isang na-leak na service-role JWT. Ang bundle-secrets detector ng FixVibe ay tumutugma sa parehong shapes.

Paano ang anon / publishable key โ€” ligtas ba iyon sa bundle?

Oo, sa disenyo. Ang anon key ay inilaan na nasa browser at ito ang ginagamit ng bawat Supabase web client. Ang kaligtasan nito ay nakasalalay nang buo sa tama na pagkaka-configure ng RLS sa bawat public na talahanayan. Tingnan ang Supabase RLS scanner na artikulo para sa kung ano ang dapat i-check.

Mga susunod na hakbang

Magpatakbo ng FixVibe scan laban sa iyong production URL โ€” ang bundle-secrets check ay libre, walang signup, at iniuulat ang service_role exposure sa wala pang isang minuto. Ipares ito sa Supabase RLS scanner na artikulo upang i-verify na ginagawa ng RLS layer ang trabaho nito, at sa Supabase storage bucket security checklist upang i-lock down ang file access. Para sa background kung bakit nagagawa nang ganoon kaaasahan ng AI tools ang leak class na ito, basahin ang Bakit nag-iiwan ng mga puwang sa seguridad ang mga AI coding tools.

// i-scan ang iyong baas surface

Hanapin ang bukas na talahanayan bago ito mahanap ng iba.

Ilagay ang isang production URL. Ine-enumerate ng FixVibe ang mga BaaS providers na kausap ng iyong app, kine-fingerprint ang kanilang mga pampublikong endpoints, at iniuulat kung ano ang mababasa o maisusulat ng isang unauthenticated client. Libre, walang install, walang card.

  • Libreng tier โ€” 3 scan / buwan, walang signup card.
  • Passive BaaS fingerprinting โ€” walang kailangang domain verification.
  • Supabase, Firebase, Clerk, Auth0, Appwrite, at iba pa.
  • Mga AI fix prompts sa bawat finding โ€” i-paste pabalik sa Cursor / Claude Code.
Supabase service role key na naka-expose sa JavaScript: ano ang ibig sabihin nito at paano ito hanapin โ€” Docs ยท FixVibe