Supabase Security
Tip
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subscription plans!
- Sluit aan by die đŹ Discord group of die telegram group of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking tricks deur PRs in te dien by die HackTricks en HackTricks Cloud github repos.
Basiese Inligting
Volgens hul landing page: Supabase is ân open source Firebase-alternatief. Begin jou projek met ân Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, en Vector embeddings.
Subdomein
Basies, wanneer ân projek geskep word, sal die gebruiker ân supabase.co subdomein ontvang soos: jnanozjdybtpqgcwhdiz.supabase.co
Database configuration
Tip
Hierdie data kan bereik word vanaf ân skakel soos
https://supabase.com/dashboard/project/<project-id>/settings/database
Hierdie database sal in ân AWS-streek ontplooi word, en om daaraan te koppel is dit moontlik om te koppel via: postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres (dit is geskep in us-west-1).
Die wagwoord is ân wagwoord wat die gebruiker tevore ingestel het.
Aangesien die subdomein bekend is en dit as username gebruik word en die AWS-streke beperk is, kan dit moontlik wees om te probeer om die wagwoord te brute force.
Hierdie afdeling bevat ook opsies om:
- Reset the database password
- Configure connection pooling
- Configure SSL: Reject plan-text connections (by default they are enabled)
- Configure Disk size
- Apply network restrictions and bans
API Configuration
Tip
Hierdie data kan bereik word vanaf ân skakel soos
https://supabase.com/dashboard/project/<project-id>/settings/api
Die URL om die supabase API in jou projek te bereik sal so lyk: https://jnanozjdybtpqgcwhdiz.supabase.co.
anon api keys
Dit sal ook ân anon API key (role: "anon"), genereer, soos: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk wat die toepassing sal moet gebruik om met die API te kommunikeer wat in ons voorbeeld blootgestel is in
Dit is moontlik om die API REST wat hierdie API kontak in die docs te vind, maar die mees interessante endpoints sou wees:
Signup (/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>Aanmelding (/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>
So, wanneer jy 'n klient ontdek wat supabase gebruik met die subdomein wat hulle toegewys is (dit is moontlik dat 'n subdomein van die maatskappy 'n CNAME oor hul supabase-subdomein het), kan jy probeer om **'n nuwe rekening op die platform te skep deur die supabase API te gebruik**.
### secret / service_role api keys
A secret API key will also be generated with **`role: "service_role"`**. Hierdie API-sleutel moet geheim gehou word omdat dit **Row Level Security** kan omseil.
Die API sleutel lyk soos dit: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
### JWT Secret
A **JWT Secret** sal ook gegenereer word sodat die toepassing **custom JWT tokens kan skep en teken**.
## Outentisering
### Aanmeldings
> [!TIP]
> Standaard sal supabase toelaat dat **nuwe gebruikers rekeninge kan skep** op jou projek deur die vroeër genoemde API-endpoints te gebruik.
Egter, hierdie nuwe rekeninge, standaard, **sal hul e-posadres moet bevestig** om in die rekening aan te meld. Dit is moontlik om **"Allow anonymous sign-ins"** te aktiveer om mense toe te laat om aan te meld sonder om hul e-pos te verifieer. Dit kan toegang gee tot **onverwagte data** (hulle kry die rolle `public` en `authenticated`).\
Dit is 'n baie slegte idee omdat supabase per aktiewe gebruiker hef, dus kan mense gebruikers skep en aanmeld en supabase sal daarvoor hef:
<figure><img src="../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
#### Auth: Server-side signup enforcement
Om die signup-knoppie in die frontend te verberg is nie genoeg nie. As die **Auth server steeds signups toelaat**, kan 'n aanvaller die API direk met die publieke `anon` key aanroep en willekeurige gebruikers skep.
Quick test (from an unauthenticated client):
```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:
- Skakel e-pos/wagwoord-registrasies in die Dashboard uit: Authentication â Providers â Email â Disable sign ups (invite-only), of stel die ekwivalente GoTrue-instelling.
- Verifieer dat die API nou 4xx teruggee vir die vorige oproep en dat geen nuwe gebruiker geskep word nie.
- As jy op invites of SSO staatmaak, maak seker dat alle ander providers gedeaktiveer is tensy dit uitdruklik nodig is.
RLS en Views: Skryf-omseiling via PostgREST
Die gebruik van ân Postgres VIEW om âsensitieweâ kolomme te âversteekâ en dit via PostgREST bloot te stel kan verander hoe voorregte geĂ«valueer word. In PostgreSQL:
- Gewone views voer standaard uit met die voorregte van die view-eienaar (definer semantics). In PG â„15 kan jy kies om
security_invokerte gebruik. - Row Level Security (RLS) geld op basistabelle. Tabel-eienaars omseil RLS tensy
FORCE ROW LEVEL SECURITYop die tabel gestel is. - Opdateerbare views kan INSERT/UPDATE/DELETE aanvaar wat dan op die basistabel toegepas word. Sonder
WITH CHECK OPTIONkan skryf-operasies wat nie by die view-predikaat pas steeds slaag.
Risikopatroon wat in die praktyk waargeneem is:
- ân Verminderde-kolom view word deur Supabase REST blootgestel en aan
anon/authenticatedtoegestaan. - PostgREST laat DML toe op die opdateerbare view en die operasie word ge-evalueer met die view-eienaar se voorregte, wat effektief die beoogde RLS-beleid op die basistabel omseil.
- Resultaat: kliënte met lae voorregte kan massaal rye wysig (bv. profiel-bios/avatars) wat hulle nie mag wysig nie.
Illustratiewe 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:
- Voorkeur om base tables bloot te stel met eksplisiete, least-privilege grants en presiese RLS-beleid.
- If you must expose a view:
- Maak dit nie-opdateerbaar nie (bv. include expressions/joins) of weier
INSERT/UPDATE/DELETEop die view aan alle onbetroubare rolle. - Enforce
ALTER VIEW <v> SET (security_invoker = on)sodat die invoker se voorregte gebruik word in plaas van die eienaar se. - On base tables, use
ALTER TABLE <t> FORCE ROW LEVEL SECURITY;sodat selfs eienaars aan RLS onderwerp is. - If allowing writes via an updatable view, add
WITH [LOCAL|CASCADED] CHECK OPTIONen aanvullende RLS op base tables om te verseker dat slegs toegelate rye geskryf/gewyzig kan word. - In Supabase, vermy om
anon/authenticatedenige write privileges op views te gee tensy jy end-to-end gedrag met toetse geverifieer het.
Detection tip:
- From
anonand anauthenticatedtest user, probeer alle CRUD-operations teen elke blootgestelde table/view. Enige suksesvolle write waar jy weiering verwag het, dui opmisconfiguration.
OpenAPI-driven CRUD probing from anon/auth roles
PostgREST exposes an OpenAPI document that you can use to enumerate all REST resources, then automatically probe allowed operations from 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[]'
Sondepatroon (voorbeelde):
- Lees ân enkele ry (verwag 401/403/200 afhangende van RLS):
curl -s "https://<PROJECT_REF>.supabase.co/rest/v1/<table>?select=*&limit=1" \
-H "apikey: <SUPABASE_ANON_KEY>" \
-H "Authorization: Bearer <SUPABASE_ANON_KEY>"
- Toets dat UPDATE geblokkeer is (gebruik ân nie-bestaande filter om te voorkom dat data tydens toetsing verander word):
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"
- Toets INSERT is geblokkeer:
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>"
- Toets DELETE is geblokkeer:
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"
Aanbevelings:
- Outomatiseer die vorige probes vir beide
anonen ân minimaalauthenticatedgebruiker en integreer dit in CI om regressies op te spoor. - Behandel elke blootgestelde table/view/function as âfirst-class surfaceâ. Moet nie aanvaar dat ân view âinheritsâ dieselfde RLS-houding as sy basis-tabelle nie.
Wagwoorde & sessies
Dit is moontlik om die minimum wagwoordlengte aan te dui (per verstek), vereistes (nie per verstek nie) en te verhoed om leaked passwords te gebruik.
Dit word aanbeveel om die vereistes te verbeter aangesien die verstekvereistes swak is.
- Gebruikersessies: Dit is moontlik om te konfigureer hoe gebruikersessies werk (timeouts, 1 sessie per gebruikerâŠ)
- Bot- en misbruikbeskerming: Dit is moontlik om Captcha te aktiveer.
SMTP-instellings
Dit is moontlik om ân SMTP in te stel om e-posse te stuur.
Gevorderde instellings
- Stel vervaltyd vir toegangstokens (3600 per verstek)
- Skakel opsporing en herroeping van moontlik gekompromiteerde refresh tokens en time-outs in
- MFA: Gee aan hoeveel MFA-faktore gelyktydig per gebruiker geregistreer kan word (10 per verstek)
- Max Direct Database Connections: Maksimum aantal konneksies wat vir auth gebruik word (10 per verstek)
- Max Request Duration: Maksimum tyd toegelaat vir ân Auth-aanvraag om te duur (10s per verstek)
Stoor
Tip
Supabase laat toe om lĂȘers te stoor en dit via ân URL toeganklik te maak (dit gebruik S3 buckets).
- Stel die oplaai-lĂȘergrootte limiet (verstek is 50MB)
- Die S3-verbinding word gegee met ân URL soos:
https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3 - Dit is moontlik om S3 access key aan te vra wat gevorm word deur ân
access key ID(bv.a37d96544d82ba90057e0e06131d0a7b) en ânsecret access key(bv.58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628)
Edge Functions
Dit is ook moontlik om geheime (secrets) te stoor in supabase wat deur edge functions toeganklik sal wees (hulle kan vanaf die web geskep en verwyder word, maar dit is nie moontlik om hul waarde direk te verkry nie).
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
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subscription plans!
- Sluit aan by die đŹ Discord group of die telegram group of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking tricks deur PRs in te dien by die HackTricks en HackTricks Cloud github repos.
HackTricks Cloud

