FixVibe

// docs / baas security / supabase service role exposure

Supabase service role key-ը բացահայտված JavaScript-ում․ ինչ է դա նշանակում, և ինչպես գտնել

Supabase service role key-ն քո տվյալների բազայի վարպետ բանալին է։ Ցանկացած ոք, ով այն ունի, շրջանցում է Row-Level Security-ն, կարող է կարդալ յուրաքանչյուր table-ի յուրաքանչյուր սյունակ և կարող է գրել կամ ջնջել ինչ ուզի։ Այն նախատեսված է ապրելու բացառապես սերվերային կողմի կոդում — երբեք զննարկիչում։ Երբ AI-ի կոդավորման գործիքն այն առաքում է JavaScript bundle-ին, քո տվյալների բազան ըստ էության հանրային է։ Այս հոդվածը բացատրում է JWT ձևը, որ բացահայտում է արտահոսած բանալին, AI-գործիքի երեք նմուշները, որոնք առաջացնում են արտահոսքը, ինչ անել առաջին ժամին հայտնաբերելուց հետո, և ինչպես ավտոմատ սկանավորել այն, քանի դեռ օգտատերերը չեն արել։

Ինչ է service role key-ը

Supabase-ը տալիս է երկու տարբեր բանալի յուրաքանչյուր նախագծի համար․ anon բանալին (նաև կոչվում է publishable key նոր նախագծերում) և service_role բանալին։ Երկուսն էլ JSON Web Token-ներ են, ստորագրված քո նախագծի JWT secret-ով։ Տարբերությունը JWT payload-ի մեջ ներդրված role claim-ն է — anon հանրային բանալու համար, service_role վարպետ բանալու համար։ PostgREST-ը, Supabase Storage-ը և Supabase Auth-ը բոլորն անցնում են շրջանցել-ամեն-ինչ ռեժիմ, երբ տեսնում են service_role claim-ը։

Ապակոդավորիր ցանկացած Supabase բանալի jwt.io-ում և նայիր payload-ին։ Service-role JWT-ի ձևն անշփոթելի է․

Service-role JWT-ի ապակոդավորված payload-ը (ցույց է տրված ստորև որպես շարահյուսությամբ ընդգծված բլոկ)։

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

Նոր Supabase նախագծերը տալիս են secret-տիպի բանալիներ sb_secret_ նախածանցով՝ JWT-ի փոխարեն։ Վարքը նույնական է — ամեն ինչ, որ կրում է sb_secret_ հանրային bundle-ում, հավասարապես աղետալի է։

Ինչպես են AI-ի կոդավորման գործիքները արտահոսում service role key-ը

Մենք տեսել ենք նույն երեք նմուշները հազարավոր vibe-coded հավելվածներում։ Ամեն մեկը սկսվում է ծրագրավորողի կողմից AI գործիքից օգնություն խնդրելով և ավարտվում service key-ի՝ bundle-ի մեջ inline արվելով։

Նմուշ 1․ Մեկ .env ֆայլ NEXT_PUBLIC_ նախածանցով

Ծրագրավորողը խնդրում է AI գործիքին «կարգավորել Supabase» և ընդունում մեկ .env երկու բանալիներով։ AI գործիքը — մարզված մարմնի վրա, որտեղ շրջակա միջավայրի փոփոխականների մեծ մասը բացահայտվում է NEXT_PUBLIC_*-ի միջոցով — երկուսին էլ նախածանցում է NEXT_PUBLIC_-ով։ Next.js-ը այդ նախածանցին համապատասխանող ամեն ինչ inline է անում client bundle-ի մեջ build-ի ժամանակ։ Թողարկիր Vercel, և service key-ն main.[hash].js-ում է։

Նմուշ 2․ Սխալ բանալի createClient կանչում

Ծրագրավորողը տեղադրում է երկու բանալիները AI-ի գեներացրած config.ts ֆայլի մեջ, և AI-ը զննարկչային createClient() կանչը սխալմամբ լրացնում է process.env.SUPABASE_SERVICE_ROLE_KEY-ով։ Build-ը ներքաշում է փոփոխականը, և JWT-ն հայտնվում է bundle-ում։

Նմուշ 3․ Service-role key-ը կոշտ կոդավորված seed սկրիպտներում

Ծրագրավորողը խնդրում է AI գործիքին գրել սկրիպտ, որ լրացնում է տվյալների բազան։ AI-ը service-role բանալին ուղղակիորեն կոշտ-կոդավորում է ֆայլում (շրջակա միջավայրից կարդալու փոխարեն), commit է անում ֆայլը repository-ին, և հանրային GitHub repo-ն կամ թողարկված հավելվածի /scripts/seed.js route-ն այժմ առաքում է բանալին։

Ինչպես է FixVibe bundle scan-ը հայտնաբերում արտահոսքը

FixVibe-ի bundle-secrets ստուգումը ներբեռնում է թողարկված հավելվածի յուրաքանչյուր JavaScript ֆայլ — entry chunk-ներ, lazy-loaded chunk-ներ, web worker-ներ, service worker-ներ — և անցկացնում է դրանք դետեկտորի միջով, որը ապակոդավորում է JWT ձևին համապատասխանող ամեն ինչ (eyJ[base64-header].eyJ[base64-payload].[signature])։ Եթե ապակոդավորված payload-ը պարունակում է "role": "service_role", սկանը հաշվետու է որպես կրիտիկական գտածո՝ ֆայլի ուղով և ճշգրիտ տողով, որտեղ բանալին հայտնվում է։ Նույն ստուգումը նաև համապատասխանում է ավելի նոր sb_secret_* նմուշին նախածանցով։

Սկանը երբեք չի վավերացվում հայտնաբերված բանալիով։ Այն բացահայտում է ձևը և հաշվետու է արտահոսքի մասին — բանալին օգտագործելը՝ շահագործելիությունն ապացուցելու համար, կլիներ չլիազորված մուտք քո տվյալների բազա։ Ապացույցը հենց JWT payload-ում է։

Հայտնաբերվել է — ինչ անել առաջին ժամին

Արտահոսած service role key-ը runtime արտակարգ իրավիճակ է։ Ենթադրիր, որ բանալին scrape արված է — հարձակվողները իրական ժամանակում հետևում են հանրային bundle-ներին։ Տվյալների բազան վերաբերվիր որպես կոմպրոմիսված, քանի դեռ չես պտտել բանալին և աուդիտ արել վերջին գործունեությունը։

  1. Անհապաղ պտտիր բանալին։ Supabase Dashboard-ում գնա Project Settings → API → Service role key → Reset։ Հին բանալին անվավեր է դառնում վայրկյանների ընթացքում։ Բանալին օգտագործող ցանկացած սերվերային կոդ պետք է թարմացվի և կրկին թողարկվի, քանի դեռ պտտումը չի տեղի ունեցել։
  2. Աուդիտ արա վերջին տվյալների բազայի գործունեությունը։ Բացիր Database → Logs dashboard-ում։ Զտիր վերջին 7 օրով։ Փնտրիր անսովոր SELECT * հարցումներ PII պարունակող table-ների դեմ, մեծ UPDATE կամ DELETE հայտարարություններ, և հարցումներ քո հայտնի ենթակառուցվածքից դուրս IP-ներից։ Supabase-ը գրառում է x-real-ip header-ը յուրաքանչյուր հարցման համար։
  3. Ստուգիր storage object-ները։ Այցելիր Storage → Logs և վերանայիր վերջին ֆայլի ներբեռնումները։ Արտահոսած service-role key-ը տալիս է շրջանցել-ամեն-ինչ մուտք նաև մասնավոր bucket-ներին։
  4. Հեռացրու բանալին source control-ից։ Նույնիսկ պտտումից հետո JWT-ն քո git պատմության մեջ թողնելը նշանակում է, որ այն հայտնաբերելի է հանրային repo-ում։ Օգտագործիր git filter-repo կամ BFG Repo-Cleaner՝ պատմությունից մաքրելու համար, ապա force-push (նախ զգուշացրու համագործակիցներին)։
  5. Կրկին սկանավորիր շտկումից հետո։ Գործարկիր թարմ FixVibe սկան կրկին թողարկված հավելվածի դեմ։ Bundle-secrets գտածոն պետք է մաքրվի։ Հաստատիր, որ ոչ մի service_role JWT և ոչ մի sb_secret_* տող չի մնում որևէ chunk-ում։

Արտահոսքը կանխելը հենց սկզբից

Կառուցվածքային շտկումը անվանման կարգապահությունն է գումարած գործիք-մակարդակի պաշտպանիչները․

  • Երբեք service key-ը մի նախածանցիր NEXT_PUBLIC_*, VITE_* կամ որևէ այլ bundle-inlining նախածանցով։ Անվանման համաձայնությունը սահման է — յուրաքանչյուր ֆրեյմվորք հարգում է այն։
  • Պահիր service key-ը ընդհանրապես .env-ից դուրս ծրագրավորողի մեքենայի վրա։ Կարդա այն secret manager-ից (Doppler, Infisical, Vercel encrypted env vars) deploy-ի ժամանակ, երբեք մի commit արա այն լոկալ։
  • <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.
  • Ավելացրու CI gate, որ սկանավորում է build output-ը։ next build-ից հետո grep արա .next/static/chunks/ output-ը service_role տողի համար։ Ձախողիր build-ը, եթե ինչ-որ բան համապատասխանում է։
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

Հաճախակի տրվող հարցեր

Որքա՞ն արագ են հարձակվողները իրականում գտնում արտահոսած Supabase service-role բանալիները։

Հանրային-bundle սկաներները րոպեների ընթացքում քայլում են նոր deployment-ներով։ Հետազոտողները փաստագրել են գործող շահագործումներ նոր Supabase նախագծերի դեմ՝ առաջին deploy-ից մեկ ժամից պակաս ժամանակում։ Service-role-ի ցանկացած բացահայտում վերաբերվիր որպես 60-րոպեանոց պատուհան, ոչ թե 60-օրյա։

Բավարա՞ր է բանալին պտտելը, թե՞ պետք է ենթադրեմ տվյալների արտահոսք։

Պտտումն անվավեր է դարձնում արտահոսած բանալին, բայց չի չեղարկում արդեն հանված տվյալները։ Եթե քո table-ները պարունակում են PII, վճարային տվյալներ կամ որևէ կարգավորվող տվյալ, դու կարող ես ունենալ ծանուցման պարտավորություն GDPR-ի (72 ժամ), CCPA-ի կամ HIPAA-ի շրջանակում։ Աուդիտ արա log-ները և խորհրդակցիր իրավաբանի հետ, եթե աուդիտը ցույց է տալիս կասկածելի մուտք։

Կարո՞ղ է RLS-ը պաշտպանել ինձ, եթե service-role բանալին արտահոսում է։

Ոչ։ Row-Level Security-ն ամբողջությամբ շրջանցվում է service_role claim-ով։ Դա նախատեսված է — բանալին գոյություն ունի հենց այն բանի համար, որ backend կոդը կարողանա շրջանցել RLS-ը admin գործողությունների համար։ Մեղմացումն այն է, որ բանալին երբեք չհասնի համատեքստի, որտեղ հարձակվողը կարող է կարդալ այն։

Կիրառվու՞մ է սա Supabase-ի նոր publishable / secret բանալու մոդելի վրա (<code>sb_publishable_</code> / <code>sb_secret_</code>)։

Այո — նույնական ռիսկի դաս։ sb_secret_* բանալին նոր secret-key ֆորմատն է, որ փոխարինում է service-role JWT-ին նոր նախագծերի համար։ Ամեն ինչ, որ կրում է sb_secret_* bundle-ում, նույնքան աղետալի է, որքան արտահոսած service-role JWT-ն։ FixVibe-ի bundle-secrets դետեկտորը համապատասխանում է երկու ձևերին։

Իսկ anon / publishable բանալին — այն անվտանգ է bundle-ում։

Այո, ըստ նախագծման։ Anon բանալին նախատեսված է ապրելու զննարկիչում և այն է, որ յուրաքանչյուր Supabase web client-ն օգտագործում է։ Նրա անվտանգությունը կախված է ամբողջությամբ RLS-ի ճիշտ կարգավորումից յուրաքանչյուր հանրային table-ի վրա։ Տես Supabase RLS սկաներ հոդվածը, թե ինչ ստուգել։

Հաջորդ քայլեր

Գործարկիր FixVibe սկան քո production URL-ի դեմ — bundle-secrets ստուգումն անվճար է, առանց գրանցման, և հաշվետու է service_role բացահայտման մասին մեկ րոպեից պակաս ժամանակում։ Զուգակցիր սա Supabase RLS սկաներ հոդվածի հետ՝ ստուգելու, որ RLS շերտն իր գործն է անում, և Supabase storage bucket-ի անվտանգության ստուգաթերթ-ի հետ՝ ֆայլի մուտքը փակելու համար։ AI գործիքների կողմից այս արտահոսքի դասը այսքան հուսալիորեն գեներացնելու ֆոնի համար կարդա Ինչու AI-ի կոդավորման գործիքները թողնում են անվտանգության բացեր։

// սկանավորիր քո baas մակերեսը

Գտիր բաց table-ը, քանի դեռ դա ուրիշը չի արել։

Մուտքագրիր production URL-ը։ FixVibe-ը թվարկում է BaaS մատակարարները, որոնց հետ խոսում է քո հավելվածը, ֆինգերփրինթ է անում իրենց հանրային endpoint-ները, և հայտնում, թե ինչ կարող է կարդալ կամ գրել չհաստատված հաճախորդը։ Անվճար, առանց տեղադրման, առանց քարտի։

  • Անվճար փաթեթ — 3 սկան ամսական, առանց գրանցման քարտի։
  • Պասիվ BaaS fingerprinting — տիրույթի հաստատում չի պահանջվում։
  • Supabase, Firebase, Clerk, Auth0, Appwrite և ավելին։
  • AI fix prompts յուրաքանչյուր գտածոյի համար — տեղադրիր Cursor / Claude Code-ում։
Գործարկիր անվճար BaaS սկան

գրանցում չի պահանջվում

Supabase service role key-ը բացահայտված JavaScript-ում․ ինչ է դա նշանակում, և ինչպես գտնել — Docs · FixVibe