Supabase Güvenlik
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- Abonelik planlarını kontrol edin!
- Katılın 💬 Discord group veya telegram group veya Twitter’da bizi takip edin 🐦 @hacktricks_live.
- PR göndererek hacking tricks paylaşın: HackTricks ve HackTricks Cloud github repos.
Temel Bilgiler
As per their landing page: Supabase is an open source Firebase alternative. Start your project with a Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, and Vector embeddings.
Alt alan adı
Genel olarak bir proje oluşturulduğunda kullanıcı şu formatta bir supabase.co alt alan adı alır: jnanozjdybtpqgcwhdiz.supabase.co
Veritabanı yapılandırması
Tip
Bu verilere şu tarz bir linkten erişilebilir:
https://supabase.com/dashboard/project/<project-id>/settings/database
Bu veritabanı belirli bir AWS bölgesinde dağıtılacaktır ve bağlanmak için şu bağlantı kullanılabilir: postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres (bu örnek us-west-1’de oluşturuldu). Parola, kullanıcının önceden belirlediği paroladır.
Bu nedenle, alt alan adı biliniyor, kullanıcı adı olarak kullanılıyor ve AWS bölgeleri sınırlı olduğundan, brute force the password denenebilir.
Bu bölüm ayrıca şu seçenekleri içerir:
- Veritabanı parolasını sıfırlama
- Connection pooling’i yapılandırma
- SSL’i yapılandırma: plan-text bağlantılarını reddet (varsayılan olarak etkinler)
- Disk boyutunu yapılandırma
- Ağ kısıtlamaları ve yasakları uygulama
API Yapılandırması
Tip
Bu verilere şu tarz bir linkten erişilebilir:
https://supabase.com/dashboard/project/<project-id>/settings/api
Projenizdeki supabase API’sine erişim URL’si şu şekilde olacaktır: https://jnanozjdybtpqgcwhdiz.supabase.co.
anon api keys
Ayrıca role: "anon" olan bir anon API key üretilir, örneğin: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk — uygulamanın API ile iletişim kurmak için kullanması gerekir.
It’s possible to find the API REST to contact this API in the docs, but the most interesting endpoints would be:
Kayıt (/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>Giriş (/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>
Yani, bir müşterinin kendisine verilen alt alan adını kullanan bir supabase istemcisi keşfettiğinizde (şirketin bir alt alanının supabase alt alanlarına CNAME koymuş olması mümkün), **supabase API**'yi kullanarak platformda yeni bir hesap oluşturmayı deneyebilirsiniz.
### secret / service_role api keys
Bir gizli API anahtarı ayrıca **`role: "service_role"`** ile oluşturulacaktır. Bu API anahtarı gizli olmalıdır çünkü **Row Level Security**'yi atlayabilecektir.
API anahtarı şöyle görünür: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
### JWT Secret
Bir **JWT Secret** de oluşturulacak, böylece uygulama **özel JWT tokenları oluşturup imzalayabilir**.
## Authentication
### Signups
> [!TIP]
> Varsayılan olarak supabase, önce bahsedilen API uç noktalarını kullanarak projenizde yeni kullanıcıların hesap oluşturmasına izin verir.
Bununla birlikte, bu yeni hesaplar varsayılan olarak **oturum açabilmek için e-posta adreslerini doğrulamak zorunda olacaklardır**. İnsanların e-posta adreslerini doğrulamadan giriş yapmalarına izin vermek için **"Allow anonymous sign-ins"** etkinleştirmek mümkündür. Bu, **beklenmeyen verilere** erişim sağlayabilir (altyapı kullanıcıları `public` ve `authenticated` rollerini alır).\ Bu çok kötü bir fikirdir çünkü supabase aktif kullanıcı başına ücretlendirir; insanlar kullanıcı oluşturup giriş yaparsa supabase bunlar için ücret alacaktır:
<figure><img src="../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
#### Auth: Server-side signup enforcement
Frontend'de kayıt butonunu gizlemek yeterli değildir. Eğer **Auth server hala kayıtlara izin veriyorsa**, bir saldırgan public `anon` anahtarıyla doğrudan API'yi çağırıp rastgele kullanıcılar oluşturabilir.
Hızlı test (kimliği doğrulanmamış bir istemciden):
```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:
- Dashboard’ta email/password kayıtlarını devre dışı bırakın: Authentication → Providers → Email → Disable sign ups (invite-only), veya eşdeğer GoTrue ayarını yapın.
- API’nin önceki çağrıya artık 4xx döndürdüğünü ve yeni bir kullanıcı oluşturulmadığını doğrulayın.
- Eğer davetler veya SSO’ya güveniyorsanız, açıkça gerekmedikçe diğer tüm providers’ın devre dışı olduğundan emin olun.
RLS and Views: Write bypass via PostgREST
Duyarlı sütunları “gizlemek” için bir Postgres VIEW kullanmak ve bunu PostgREST üzerinden açığa çıkarmak, ayrıcalıkların nasıl değerlendirildiğini değiştirebilir. In PostgreSQL:
- Ordinary views varsayılan olarak view sahibinin ayrıcalıklarıyla çalışır (definer semantics). PG ≥15’te
security_invoker’a geçiş yapabilirsiniz. - Row Level Security (RLS) temel tablolarda uygulanır. Tablo sahipleri, tabloya
FORCE ROW LEVEL SECURITYayarı yapılmadıkça RLS’yi atlar. - Updatable views INSERT/UPDATE/DELETE kabul edebilir ve bunlar daha sonra base tabloya uygulanır.
WITH CHECK OPTIONyoksa, view predicate’ine uymayan yazma işlemleri yine de başarılı olabilir.
Risk pattern observed in the wild:
- Azaltılmış sütunlu bir view Supabase REST üzerinden açığa çıkarılır ve
anon/authenticated’a yetki verilir. - PostgREST, updatable view üzerinde DML’e izin verir ve işlem view sahibinin ayrıcalıklarıyla değerlendirilir; bu da base tablodaki amaçlanan RLS politikalarını fiilen atlatır.
- Sonuç: düşük ayrıcalıklı istemciler, değiştirmemeleri gereken satırları (ör. profile bios/avatars) topluca düzenleyebilir.
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:
- Tabloları doğrudan, açıkça belirtilmiş asgari ayrıcalık izinleri ve hassas RLS politikalarıyla açığa çıkarmayı tercih edin.
- Bir görünümü açığa çıkarmanız gerekiyorsa:
- Güncellenemez yapın (ör. expressions/joins içerecek şekilde) veya tüm güvensiz rollere görünümde
INSERT/UPDATE/DELETE’i reddedin. ALTER VIEW <v> SET (security_invoker = on)uygulanmasını sağlayın; böylece invoker’ın ayrıcalıkları owner’ınkiler yerine kullanılır.- Temel tablolarda
ALTER TABLE <t> FORCE ROW LEVEL SECURITY;kullanın; böylece sahipler bile RLS’e tabi olur. - Eğer updatable bir görünüm aracılığıyla yazılara izin veriyorsanız,
WITH [LOCAL|CASCADED] CHECK OPTIONekleyin ve temel tablolarda tamamlayıcı RLS ile yalnızca izin verilen satırların yazılabileceğinden/değiştirilebileceğinden emin olun. - Supabase’de, end-to-end davranışı testlerle doğrulamamışsanız, view’lar üzerinde
anon/authenticatedrollerine herhangi bir yazma ayrıcalığı vermekten kaçının.
Detection tip:
anonve birauthenticatedtest kullanıcısı ile her açığa çıkarılmış tablo/görünüm üzerinde tüm CRUD işlemlerini deneyin. Reddedilmesini beklediğiniz halde başarılı olan herhangi bir yazma, bir yanlış yapılandırmaya işaret eder.
OpenAPI-driven CRUD probing from anon/auth roles
PostgREST, tüm REST kaynaklarını numaralandırmak ve ardından düşük ayrıcalıklı rollerden izin verilen işlemleri otomatik olarak probe etmek için kullanabileceğiniz bir OpenAPI belgesi sunar.
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 deseni (örnekler):
- Tek bir satırı oku (beklenen 401/403/200, RLS’e bağlı olarak):
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 testi engellenmiş (test sırasında verileri değiştirmemek için var olmayan bir filtre kullanın):
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"
- Test INSERT engellendi:
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>"
- Test DELETE engellenmiş:
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"
Öneriler:
- Önceki taramaları hem
anonhem de minimum düzeydeauthenticatedkullanıcı için otomatikleştir ve regresyonları yakalamak için CI’ye entegre et. - Her açık tablo/görünüm/fonksiyonu birinci sınıf bir yüzey olarak ele al. Bir görünümün “inherits” ile base tablolarıyla aynı RLS duruşunu varsayma.
Parolalar & oturumlar
It’s possible to indicate the minimum password length (by default), requirements (no by default) and disallow to use leaked passwords.
Varsayılan gereksinimler zayıf olduğu için gereksinimleri geliştirmeniz önerilir.
- User Sessions: Kullanıcı oturumlarının nasıl çalışacağını yapılandırmak mümkün (zaman aşımı, kullanıcı başına 1 oturum…)
- Bot and Abuse Protection: Captcha’yı etkinleştirmek mümkün.
SMTP Settings
E-posta göndermek için bir SMTP ayarlamak mümkün.
Advanced Settings
- Set expire time to access tokens (3600 by default)
- Potansiyel olarak ele geçirilmiş refresh token’ları tespit edip iptal etmek ve timeout ayarlamak mümkün
- MFA: Bir kullanıcının aynı anda kaç MFA faktörü kaydedebileceğini belirt (varsayılan 10)
- Max Direct Database Connections: Kimlik doğrulama için kullanılacak maksimum bağlantı sayısı (varsayılan 10)
- Max Request Duration: Bir Auth isteğinin sürebileceği maksimum süre (varsayılan 10s)
Storage
Tip
Supabase allows to store files and make them accesible over a URL (it uses S3 buckets).
- Yükleme dosya boyutu limitini ayarla (varsayılan 50MB)
- The S3 connection is given with a URL like:
https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3 - S3 access key talep etmek mümkün; bunlar bir
access key ID(e.g.a37d96544d82ba90057e0e06131d0a7b) ve birsecret access key(e.g.58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628) şeklinde oluşur
Edge Functions
Supabase içinde gizli bilgileri saklamak de mümkün olup bunlar edge functions tarafından erişilebilir (web üzerinden oluşturulup silinebilirler, ancak değerlerine doğrudan erişim mümkün değildir).
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 Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- Abonelik planlarını kontrol edin!
- Katılın 💬 Discord group veya telegram group veya Twitter’da bizi takip edin 🐦 @hacktricks_live.
- PR göndererek hacking tricks paylaşın: HackTricks ve HackTricks Cloud github repos.
HackTricks Cloud

