// docs / baas security / supabase service role exposure
JavaScript में Supabase service role key उजागर: इसका क्या मतलब है और इसे कैसे ढूँढ़ें
Supabase service role key आपके database की master key है। इसे रखने वाला कोई भी व्यक्ति Row-Level Security को bypass करता है, हर table के हर column को पढ़ सकता है, और जो चाहे लिख या delete कर सकता है। इसे विशेष रूप से server-side कोड में रहने के लिए design किया गया है — कभी browser में नहीं। जब एक AI कोडिंग टूल इसे JavaScript bundle में ship करता है, तो आपका database, वास्तव में, public होता है। यह लेख JWT shape जो leaked key की पहचान करता है, leak उत्पन्न करने वाले तीन AI-tool patterns, detection के पहले घंटे में क्या करना है, और users से पहले इसे अपने आप scan कैसे करें, यह समझाता है।
Service role key क्या है
Supabase हर project के लिए दो भिन्न keys जारी करता है: anon key (नए projects में publishable key भी कहा जाता है) और service_role key। दोनों आपके project की JWT secret द्वारा signed JSON Web Tokens हैं। अंतर JWT payload में बेक किया गया role claim है — public key के लिए anon, master key के लिए service_role। PostgREST, Supabase Storage, और Supabase Auth सभी service_role claim देखते ही bypass-everything mode में switch हो जाते हैं।
किसी भी Supabase key को jwt.io पर decode करें और payload देखें। एक service-role JWT का आकार स्पष्ट है:
एक service-role JWT का decoded payload (नीचे syntax-highlighted block के रूप में दिखाया गया है)।
{
"iss": "supabase",
"ref": "[project-ref]",
"role": "service_role",
"iat": 1700000000,
"exp": 2000000000
}नए Supabase projects JWT के बजाय sb_secret_ prefix वाली secret-style keys जारी करते हैं। Behaviour समान है — एक public bundle में sb_secret_ ले जाने वाली कोई भी चीज़ समान रूप से विनाशकारी है।
AI कोडिंग टूल service role key को कैसे leak करते हैं
हमने हज़ारों vibe-coded apps में वही तीन patterns देखे हैं। हर एक developer के AI टूल से मदद माँगने से शुरू होता है और service key के bundle में inline होने पर समाप्त होता है।
Pattern 1: NEXT_PUBLIC_ prefix वाली एकल .env file
Developer AI टूल से "Supabase setup करो" कहता है और एक एकल .env स्वीकार करता है जिसमें दोनों keys हैं। AI टूल — एक corpus पर प्रशिक्षित जिसमें अधिकांश environment variables NEXT_PUBLIC_* के माध्यम से exposed हैं — दोनों को NEXT_PUBLIC_ से prefix कर देता है। Next.js build time पर इस prefix से मेल खाने वाली किसी भी चीज़ को client bundle में inline कर देता है। Vercel पर ship करें, और service key main.[hash].js में है।
Pattern 2: createClient call में गलत key
Developer दोनों keys को AI द्वारा generated एक config.ts file में paste करता है, और AI browser-side createClient() call को गलती से process.env.SUPABASE_SERVICE_ROLE_KEY से populate कर देता है। Build variable को pull करता है, और JWT bundle में आ जाता है।
Pattern 3: Seed scripts में hardcoded service-role key
Developer AI टूल से database को seed करने वाली script लिखने को कहता है। AI service-role key को सीधे file में hardcode कर देता है (environment से पढ़ने के बजाय), file को repository में commit कर देता है, और public GitHub repo या deployed app का /scripts/seed.js route अब key serve कर रहा है।
FixVibe bundle scan leak को कैसे detect करता है
FixVibe का bundle-secrets check deployed app द्वारा referenced हर JavaScript file को download करता है — entry chunks, lazy-loaded chunks, web workers, service workers — और उन्हें एक detector के माध्यम से चलाता है जो JWT shape (eyJ[base64-header].eyJ[base64-payload].[signature]) से मेल खाने वाली किसी भी चीज़ को decode करता है। यदि decoded payload में "role": "service_role" है, तो scan इसे file path और key के सटीक line के साथ एक critical finding के रूप में report करता है। वही check prefix से नए sb_secret_* pattern को भी match करता है।
Scan कभी भी खोजी गई key के साथ authenticate नहीं करता। यह shape की पहचान करता है और leak की report करता है — exploitability साबित करने के लिए key का उपयोग करना आपके database तक अनधिकृत पहुँच होगी। प्रमाण JWT payload में ही है।
Detected — पहले घंटे में क्या करें
एक leaked service role key एक runtime emergency है। मान लें कि key scrape कर ली गई है — हमलावर public bundles को real time में monitor करते हैं। Database को compromised मानें जब तक आपने key rotate नहीं की और recent activity का audit नहीं किया।
- Key तुरंत rotate करें। Supabase Dashboard में, Project Settings → API → Service role key → Reset पर जाएँ। पुरानी key सेकंड में अमान्य हो जाती है। Key का उपयोग करने वाला कोई भी service-side कोड rotation आने से पहले update और redeploy होना चाहिए।
- हाल की database activity का audit करें। Dashboard में Database → Logs खोलें। पिछले 7 दिनों पर filter करें। PII वाली tables पर असामान्य
SELECT *queries, बड़ेUPDATEयाDELETEstatements, और आपके ज्ञात infrastructure के बाहर IPs से requests देखें। Supabase हर request परx-real-ipheader log करता है। - Storage objects check करें। Storage → Logs पर जाएँ और हाल के file downloads की समीक्षा करें। एक leaked service-role key private buckets तक भी bypass-everything पहुँच देती है।
- Source control से key हटाएँ। Rotation के बाद भी, अपने git history में JWT छोड़ना मतलब public repo में यह खोजी जा सकती है। इसे history से scrub करने के लिए
git filter-repoया BFG Repo-Cleaner का उपयोग करें, फिर force-push करें (पहले collaborators को चेतावनी दें)। - Fix के बाद दोबारा scan करें। Redeployed app के विरुद्ध एक fresh FixVibe scan चलाएँ। Bundle-secrets finding साफ़ हो जानी चाहिए। Confirm करें कि किसी भी chunk में कोई
service_roleJWT और कोईsb_secret_*string नहीं रहती।
Leak को पहले स्थान पर रोकना
Structural फ़िक्स नामकरण अनुशासन और tool-level guardrails है:
- Service key को कभी
NEXT_PUBLIC_*,VITE_*, या किसी अन्य bundle-inlining prefix से prefix न करें। Naming convention boundary है — हर framework इसका सम्मान करता है। - Developer machine पर
.envसे service key को पूरी तरह बाहर रखें। Deploy पर इसे secret manager (Doppler, Infisical, Vercel encrypted env vars) से पढ़ें, इसे कभी locally 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.
- Build output को scan करने वाला एक CI gate जोड़ें।
next buildके बाद,.next/static/chunks/output मेंservice_rolestring के लिए grep करें। यदि कुछ भी मेल खाता है तो build को fail करें।
# 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अक्सर पूछे जाने वाले प्रश्न
हमलावर वास्तव में leaked Supabase service-role keys कितनी जल्दी ढूँढ़ लेते हैं?
Public-bundle scanners मिनटों के भीतर नए deployments को scan करते हैं। शोधकर्ताओं ने पहले deploy से एक घंटे के भीतर नए Supabase projects के विरुद्ध working exploits को documented किया है। किसी भी service-role exposure को 60-मिनट की window मानें, 60-दिन की नहीं।
क्या key rotate करना पर्याप्त है, या मुझे data exfiltration मानना होगा?
Rotation leaked key को अमान्य करती है पर पहले से खींचे गए data को undo नहीं करती। यदि आपकी tables में PII, payment data, या कोई regulated data है, तो आपके पास GDPR (72 घंटे), CCPA, या HIPAA के तहत notification obligation हो सकती है। Logs का audit करें और यदि audit संदिग्ध access दिखाता है तो legal counsel से सलाह लें।
क्या service-role key leak होने पर RLS मेरी सुरक्षा कर सकता है?
नहीं। Row-Level Security service_role claim द्वारा पूरी तरह bypass की जाती है। यह design के अनुसार है — key विशेष रूप से इसलिए मौजूद है ताकि backend कोड admin operations के लिए RLS को skip कर सके। Mitigation यह सुनिश्चित करना है कि key कभी ऐसे context में न पहुँचे जहाँ एक हमलावर इसे पढ़ सके।
क्या यह नए Supabase publishable / secret key model (<code>sb_publishable_</code> / <code>sb_secret_</code>) पर लागू होता है?
हाँ — समान risk class। sb_secret_* key नया secret-key format है जो नए projects के लिए service-role JWT को replace करता है। एक bundle में sb_secret_* ले जाने वाली कोई भी चीज़ leaked service-role JWT जितनी ही विनाशकारी है। FixVibe का bundle-secrets detector दोनों shapes को match करता है।
Anon / publishable key के बारे में क्या — क्या वह bundle में सुरक्षित है?
हाँ, design के अनुसार। Anon key को browser में रहने के लिए design किया गया है और यह वही है जिसका हर Supabase web client उपयोग करता है। इसकी सुरक्षा पूरी तरह से हर public table पर सही ढंग से कॉन्फ़िगर की गई RLS पर निर्भर करती है। क्या check करना है, इसके लिए Supabase RLS scanner लेख देखें।
अगले कदम
अपने production URL के विरुद्ध एक FixVibe scan चलाएँ — bundle-secrets check मुफ़्त है, बिना signup, और एक मिनट से कम में service_role exposure की report करता है। RLS layer अपना काम कर रही है यह verify करने के लिए इसे Supabase RLS scanner लेख के साथ pair करें, और file access को lock down करने के लिए Supabase storage bucket security checklist। AI टूल इस leak class को इतनी विश्वसनीयता से क्यों generate करते हैं, इसकी पृष्ठभूमि के लिए, AI कोडिंग टूल security gaps क्यों छोड़ते हैं पढ़ें।
