Supabase सुरक्षा
Reading time: 12 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें, PRs को HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में सबमिट करके।
बुनियादी जानकारी
As per their landing page: Supabase is an open source Firebase alternative. अपने प्रोजेक्ट की शुरुआत Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, and Vector embeddings के साथ करें।
Subdomain
जब कोई project बनाया जाता है, user को एक supabase.co subdomain मिलेगा जैसे: jnanozjdybtpqgcwhdiz.supabase.co
डेटाबेस कॉन्फ़िगरेशन
tip
यह डेटा इस तरह के लिंक से एक्सेस किया जा सकता है https://supabase.com/dashboard/project/<project-id>/settings/database
यह database किसी AWS region में deploy होगा, और इसे कनेक्ट करने के लिए आप इस तरह कनेक्ट कर सकते हैं: postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres (this was crated in us-west-1).
पासवर्ड वह password है जो user ने पहले डाला था।
इसलिए, चूंकि subdomain ज्ञात है और इसे username के रूप में उपयोग किया जाता है और AWS regions सीमित हैं, इसलिए संभव है कि पासवर्ड को brute force the password करने की कोशिश की जा सके।
इस सेक्शन में निम्न विकल्प भी होते हैं:
- डेटाबेस पासवर्ड रीसेट करें
- कनेक्शन पूलिंग कॉन्फ़िगर करें
- Configure SSL: प्लेन-टेक्स्ट कनेक्शनों को अस्वीकार करें (डिफ़ॉल्ट रूप से वे सक्षम होते हैं)
- डिस्क साइज कॉन्फ़िगर करें
- नेटवर्क प्रतिबंध और बैन लागू करें
API कॉन्फ़िगरेशन
tip
यह डेटा इस तरह के लिंक से एक्सेस किया जा सकता है https://supabase.com/dashboard/project/<project-id>/settings/api
अपने प्रोजेक्ट के supabase API तक पहुँचने के लिए URL इस तरह होगा: https://jnanozjdybtpqgcwhdiz.supabase.co.
anon api keys
यह एक anon API key (role: "anon"), जैसे: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk भी जेनरेट करेगा, जिसे application को API से संपर्क करने के लिए उपयोग करना होगा जो हमारे example में एक्सपोज़ किया गया है
इस API से संपर्क करने के लिए API REST आप docs में पा सकते हैं, लेकिन सबसे दिलचस्प endpoints होंगे:
साइनअप (/auth/v1/signup)
``` POST /auth/v1/signup HTTP/2 Host: id.io.net Content-Length: 90 X-Client-Info: supabase-js-web/2.39.2 Sec-Ch-Ua: "Not-A.Brand";v="99", "Chromium";v="124" Sec-Ch-Ua-Mobile: ?0 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.60 Safari/537.36 Content-Type: application/json;charset=UTF-8 Apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk Sec-Ch-Ua-Platform: "macOS" Accept: */* Origin: https://cloud.io.net Sec-Fetch-Site: same-site Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: https://cloud.io.net/ Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Priority: u=1, i{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
</details>
<details>
<summary>लॉगिन (/auth/v1/token?grant_type=password)</summary>
POST /auth/v1/token?grant_type=password HTTP/2 Host: hypzbtgspjkludjcnjxl.supabase.co Content-Length: 80 X-Client-Info: supabase-js-web/2.39.2 Sec-Ch-Ua: "Not-A.Brand";v="99", "Chromium";v="124" Sec-Ch-Ua-Mobile: ?0 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.60 Safari/537.36 Content-Type: application/json;charset=UTF-8 Apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk Sec-Ch-Ua-Platform: "macOS" Accept: / Origin: https://cloud.io.net Sec-Fetch-Site: same-site Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: https://cloud.io.net/ Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Priority: u=1, i
{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
</details>
तो, जब भी आप किसी क्लाइंट को उनके दिए गए सबडोमेन के साथ supabase का उपयोग करते हुए पाते हैं (संभव है कि कंपनी का कोई सबडोमेन उनके supabase सबडोमेन पर CNAME कर दिया गया हो), तो आप **supabase API का उपयोग करके प्लेटफ़ॉर्म पर एक नया अकाउंट बना कर देख सकते हैं**।
### गुप्त / service_role API keys
एक गुप्त API key भी जनरेट होगी जिसमें **`role: "service_role"`** होगा। यह API key गुप्त रखनी चाहिए क्योंकि यह **Row Level Security** को बायपास कर पाएगी।
The API key looks like this: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
### JWT Secret
एक **JWT Secret** भी जनरेट किया जाएगा ताकि एप्लिकेशन **कस्टम JWT टोकन बना कर साइन** कर सके।
## प्रमाणीकरण
### Signups
<div class="mdbook-alerts mdbook-alerts-tip">
<p class="mdbook-alerts-title">
<span class="mdbook-alerts-icon"></span>
tip
</p>
डिफ़ॉल्ट रूप से supabase आपके प्रोजेक्ट पर पहले बताए गए API endpoints का उपयोग करके **नए उपयोगकर्ताओं को अकाउंट बनाने** की अनुमति देगा।
</div>
हालाँकि, ये नए अकाउंट्स, डिफ़ॉल्ट रूप से, **लॉगिन करने के लिए अपना ईमेल पता सत्यापित करना आवश्यक होगा**। यह संभव है कि **"Allow anonymous sign-ins"** सक्षम किया जा सके ताकि लोग अपना ईमेल सत्यापित किए बिना लॉगिन कर सकें। इससे उन्हें **अनपेक्षित डेटा** तक पहुंच मिल सकती है (उन्हें `public` और `authenticated` रोल मिलते हैं)।\
यह बहुत बुरा विचार है क्योंकि supabase सक्रिय उपयोगकर्ता के आधार पर चार्ज करता है, इसलिए लोग यूज़र्स बना कर लॉगिन कर सकते हैं और supabase उन पर चार्ज कर देगा:
<figure><img src="../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
#### Auth: सर्वर-साइड साइनअप प्रवर्तन
Frontend में signup बटन छिपाना पर्याप्त नहीं है। अगर **Auth सर्वर अभी भी signups की अनुमति देता है**, तो एक हमलावर सीधे API को सार्वजनिक `anon` key के साथ कॉल कर सकता है और मनमाने उपयोगकर्ता बना सकता है।
त्वरित परीक्षण (एक अनप्रमाणित क्लाइंट से):
<div class="codeblock_filename_container"><span class="codeblock_filename_inner hljs">bash</span></div>
```bash
curl -X POST \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
-H "Content-Type: application/json" \
-d '{"email":"attacker@example.com","password":"Sup3rStr0ng!"}' \
https://<PROJECT_REF>.supabase.co/auth/v1/signup
Expected hardening:
- Disable email/password signups in the Dashboard: Authentication → Providers → Email → Disable sign ups (invite-only), or set the equivalent GoTrue setting.
- Verify the API now returns 4xx to the previous call and no new user is created.
- If you rely on invites or SSO, ensure all other providers are disabled unless explicitly needed.
RLS and Views: Write bypass via PostgREST
Using a Postgres VIEW to “hide” sensitive columns and exposing it via PostgREST can change how privileges are evaluated. In PostgreSQL:
- Ordinary views execute with the privileges of the view owner by default (definer semantics). In PG ≥15 you can opt into
security_invoker. - Row Level Security (RLS) applies on base tables. Table owners bypass RLS unless
FORCE ROW LEVEL SECURITYis set on the table. - Updatable views can accept INSERT/UPDATE/DELETE that are then applied to the base table. Without
WITH CHECK OPTION, writes that don’t match the view predicate may still succeed.
Risk pattern observed in the wild:
- A reduced-column view is exposed through Supabase REST and granted to
anon/authenticated. - PostgREST allows DML on the updatable view and the operation is evaluated with the view owner’s privileges, effectively bypassing the intended RLS policies on the base table.
- Result: low-privileged clients can mass-edit rows (e.g., profile bios/avatars) they should not be able to modify.
Illustrative write via view (attempted from a public client):
curl -X PATCH \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
-H "Content-Type: application/json" \
-H "Prefer: return=representation" \
-d '{"bio":"pwned","avatar_url":"https://i.example/pwn.png"}' \
"https://<PROJECT_REF>.supabase.co/rest/v1/users_view?id=eq.<victim_user_id>"
Hardening checklist for views and RLS:
- बेस टेबल्स को स्पष्ट, न्यूनतम-प्रिविलेज ग्रांट्स और सटीक RLS नीतियों के साथ एक्सपोज़ करना प्राथमिकता दें।
- यदि आपको किसी view को एक्सपोज़ करना ही है:
- इसे non-updatable बनाएं (उदा., expressions/joins शामिल करके) या सभी untrusted roles के लिए view पर
INSERT/UPDATE/DELETEको deny करें। - लागू करें
ALTER VIEW <v> SET (security_invoker = on)ताकि owner के बजाय invoker के privileges का उपयोग हो। - बेस टेबल्स पर
ALTER TABLE <t> FORCE ROW LEVEL SECURITY;का उपयोग करें ताकि मालिक भी RLS के अधीन हों। - अगर updatable view के माध्यम से लिखने की अनुमति दे रहे हैं, तो
WITH [LOCAL|CASCADED] CHECK OPTIONऔर बेस टेबल्स पर समकक्ष RLS जोड़ें ताकि केवल अनुमत rows ही लिखे/बदलें जा सकें। - Supabase में, तब तक
anon/authenticatedको views पर कोई write privileges न दें जब तक आपने end-to-end व्यवहार को tests से सत्यापित न कर लिया हो।
Detection tip:
anonऔर एकauthenticatedटेस्ट यूज़र से, हर एक्सपोज्ड table/view के खिलाफ सभी CRUD ऑपरेशन्स आजमाएँ। जहाँ denial की उम्मीद थी वहां कोई सफल write हो तो वह misconfiguration का संकेत है।
OpenAPI-driven CRUD probing from anon/auth roles
PostgREST एक OpenAPI दस्तावेज़ एक्सपोज़ करता है जिसका उपयोग आप सभी REST resources को सूचीबद्ध करने के लिए कर सकते हैं, और फिर low-privileged roles से स्वचालित रूप से अनुमत ऑपरेशन्स को प्रोब कर सकते हैं।
Fetch the OpenAPI (works with the public anon key):
curl -s https://<PROJECT_REF>.supabase.co/rest/v1/ \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
-H "Accept: application/openapi+json" | jq '.paths | keys[]'
Probe pattern (examples):
- एक पंक्ति पढ़ें (RLS के अनुसार 401/403/200 की उम्मीद):
curl -s "https://<PROJECT_REF>.supabase.co/rest/v1/<table>?select=*&limit=1" \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>"
- टेस्ट UPDATE ब्लॉक किया गया है (टेस्टिंग के दौरान डेटा में परिवर्तन से बचने के लिए एक गैर-मौजूद filter का उपयोग करें):
curl -i -X PATCH \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
-H "Content-Type: application/json" \
-H "Prefer: return=minimal" \
-d '{"__probe":true}' \
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
- टेस्ट INSERT ब्लॉक किया गया है:
curl -i -X POST \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
-H "Content-Type: application/json" \
-H "Prefer: return=minimal" \
-d '{"__probe":true}' \
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>"
- टेस्ट DELETE अवरुद्ध है:
curl -i -X DELETE \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
Recommendations:
- पहले किए गए प्रोब्स को
anonऔर न्यूनतम रूप सेauthenticatedउपयोगकर्ता दोनों के लिए ऑटोमेट करें और रिग्रेशन पकड़ने के लिए उन्हें CI में इंटीग्रेट करें। - प्रत्येक एक्सपोज़ की गई टेबल/व्यू/फ़ंक्शन को एक प्रथम-श्रेणी सतह की तरह मानें। यह न मानें कि कोई view उसके base tables के समान RLS स्थिति “inherits” करता है।
पासवर्ड और सत्र
यह संभव है कि न्यूनतम पासवर्ड लंबाई (डिफ़ॉल्ट रूप से), आवश्यकताएँ (डिफ़ॉल्ट रूप से नहीं) और leaked पासवर्ड का उपयोग न करने का विकल्प निर्धारित किया जा सके।
सुझाया जाता है कि डिफ़ॉल्ट आवश्यकताओं को सुधारें क्योंकि वे कमजोर हैं।
- User Sessions: यह कॉन्फ़िगर करना संभव है कि user sessions कैसे काम करें (timeouts, 1 session per user...)
- Bot and Abuse Protection: Captcha सक्षम किया जा सकता है।
SMTP Settings
ईमेल भेजने के लिए SMTP सेट करना संभव है।
उन्नत सेटिंग्स
- access tokens के लिए expire time सेट करें (3600 डिफ़ॉल्ट)
- संभावित रूप से compromised refresh tokens का पता लगाने और revoke करने तथा timeout सेट करने का विकल्प
- MFA: यह निर्दिष्ट करें कि प्रति उपयोगकर्ता एक साथ कितने MFA factors enroll किए जा सकते हैं (डिफ़ॉल्ट 10)
- Max Direct Database Connections: auth के लिए उपयोग किए जाने वाले कनेक्शनों की अधिकतम संख्या (डिफ़ॉल्ट 10)
- Max Request Duration: Auth request के लिए अनुमत अधिकतम समय (डिफ़ॉल्ट 10s)
Storage
tip
Supabase आपको फ़ाइलें स्टोर करने की अनुमति देता है और उन्हें URL के माध्यम से उपलब्ध कराता है (यह S3 buckets का उपयोग करता है)।
- अपलोड फ़ाइल आकार सीमा सेट करें (डिफ़ॉल्ट 50MB है)
- S3 कनेक्शन एक URL के साथ दिया जाता है जैसे:
https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3 - आप request S3 access key कर सकते हैं जो एक
access key ID(उदा.a37d96544d82ba90057e0e06131d0a7b) और एकsecret access key(उदा.58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628) से बनती हैं
Edge Functions
supabase में भी store secrets करना संभव है जो accessible by edge functions होंगे (इन्हें web से बनाया और deleted किया जा सकता है, लेकिन उनके मान तक सीधे पहुंचना संभव नहीं है)।
References
- Building Hacker Communities: Bug Bounty Village, getDisclosed’s Supabase Misconfig, and the LHE Squad (Ep. 133) – YouTube
- Critical Thinking Podcast – Episode 133 page
- Supabase: Row Level Security (RLS)
- PostgreSQL: Row Security Policies
- PostgreSQL: CREATE VIEW (security_invoker, check option)
- PostgREST: OpenAPI documentation
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें, PRs को HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में सबमिट करके।
HackTricks Cloud