Translated ['', 'src/pentesting-ci-cd/supabase-security.md'] to af

This commit is contained in:
Translator
2025-09-29 23:08:56 +00:00
parent 44890bfac0
commit 096f908055

View File

@@ -1,45 +1,45 @@
# Supabase Sekuriteit
# Supabase Security
{{#include ../banners/hacktricks-training.md}}
## Basiese Inligting
Volgens hul [**landing page**](https://supabase.com/): Supabase is 'n oopbron Firebase alternatief. Begin jou projek met 'n Postgres databasis, Verifikasie, onmiddellike API's, Edge Funksies, Realtime intekeninge, Berging, en Vektor inbedings.
Volgens hul [**landing page**](https://supabase.com/): 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`**
Basies, wanneer 'n projek geskep word, sal die gebruiker 'n supabase.co subdomein ontvang soos: **`jnanozjdybtpqgcwhdiz.supabase.co`**
## **Databasis konfigurasie**
## **Database configuration**
> [!TIP]
> **Hierdie data kan vanaf 'n skakel soos `https://supabase.com/dashboard/project/<project-id>/settings/database` verkry word**
> **Hierdie data kan bereik word vanaf 'n skakel soos `https://supabase.com/dashboard/project/<project-id>/settings/database`**
Hierdie **databasis** sal in 'n AWS streek ontplooi word, en om daartoe te verbind, sal dit moontlik wees om te verbind met: `postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres` (dit is in us-west-1 geskep).\
Die wagwoord is 'n **wagwoord wat die gebruiker vroeër ingevoer het**.
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**.
Daarom, aangesien die subdomein 'n bekende een is en dit as gebruikersnaam gebruik word en die AWS streke beperk is, mag dit moontlik wees om te probeer om die **wagwoord te brute force**.
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:
- Die databasis wagwoord te herstel
- Verbinding pooling te konfigureer
- SSL te konfigureer: Weier plan-kleur verbindings (standaard is dit geaktiveer)
- Skyf grootte te konfigureer
- Netwerk beperkings en verbande toe te pas
- 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 Konfigurasie
## API Configuration
> [!TIP]
> **Hierdie data kan vanaf 'n skakel soos `https://supabase.com/dashboard/project/<project-id>/settings/api` verkry word**
> **Hierdie data kan bereik word vanaf 'n skakel soos `https://supabase.com/dashboard/project/<project-id>/settings/api`**
Die URL om toegang te verkry tot die supabase API in jou projek sal wees: `https://jnanozjdybtpqgcwhdiz.supabase.co`.
Die URL om die supabase API in jou projek te bereik sal so lyk: `https://jnanozjdybtpqgcwhdiz.supabase.co`.
### anon api sleutels
### anon api keys
Dit sal ook 'n **anon API sleutel** genereer (`role: "anon"`), soos: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk` wat die toepassing nodig sal hê om te gebruik om die API sleutel blootgestel in ons voorbeeld te kontak.
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 te vind om hierdie API te kontak in die [**docs**](https://supabase.com/docs/reference/self-hosting-auth/returns-the-configuration-settings-for-the-gotrue-server), maar die mees interessante eindpunte sal wees:
Dit is moontlik om die API REST wat hierdie API kontak in die [**docs**](https://supabase.com/docs/reference/self-hosting-auth/returns-the-configuration-settings-for-the-gotrue-server) te vind, maar die mees interessante endpoints sou wees:
<details>
@@ -72,7 +72,7 @@ Priority: u=1, i
<details>
<summary>Inlog (/auth/v1/token?grant_type=password)</summary>
<summary>Aanmelding (/auth/v1/token?grant_type=password)</summary>
```
POST /auth/v1/token?grant_type=password HTTP/2
Host: hypzbtgspjkludjcnjxl.supabase.co
@@ -99,61 +99,171 @@ Priority: u=1, i
```
</details>
So, wanneer jy 'n kliënt ontdek wat supabase gebruik met die subdomein wat aan hulle toegeken is (dit is moontlik dat 'n subdomein van die maatskappy 'n CNAME oor hul supabase subdomein het), kan jy probeer om **'n nuwe rekening in die platform te skep met die supabase API**.
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**.
### geheim / diensrol API sleutels
### secret / service_role api keys
'n Geheime API-sleutel sal ook gegenereer word met **`role: "service_role"`**. Hierdie API-sleutel moet geheim wees omdat dit in staat sal wees om **Row Level Security** te omseil.
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 volg: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
Die API sleutel lyk soos dit: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
### JWT Geheim
### JWT Secret
'n **JWT Geheim** sal ook gegenereer word sodat die toepassing **aangepaste JWT tokens kan skep en teken**.
A **JWT Secret** sal ook gegenereer word sodat die toepassing **custom JWT tokens kan skep en teken**.
## Verifikasie
## Outentisering
### Teken in
### Aanmeldings
> [!TIP]
> Deur **standaard** sal supabase **nuwe gebruikers toelaat om rekeninge te skep** op jou projek deur die voorheen genoemde API eindpunte te gebruik.
> Standaard sal supabase toelaat dat **nuwe gebruikers rekeninge kan skep** op jou projek deur die vroeër genoemde API-endpoints te gebruik.
E however, hierdie nuwe rekeninge, standaard, **sal hul e-posadres moet verifieer** om in die rekening in te log. Dit is moontlik om **"Laat anonieme aanmeldings toe"** in te skakel om mense toe te laat om in te log sonder om hul e-posadres te verifieer. Dit kan toegang tot **onverwagte data** verleen (hulle kry die rolle `public` en `authenticated`).\
Dit is 'n baie slegte idee omdat supabase per aktiewe gebruiker hef, so mense kan gebruikers skep en inlog en supabase sal vir hulle hef:
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_invoker` te gebruik.
- Row Level Security (RLS) geld op basistabelle. Tabel-eienaars omseil RLS tensy `FORCE ROW LEVEL SECURITY` op die tabel gestel is.
- Opdateerbare views kan INSERT/UPDATE/DELETE aanvaar wat dan op die basistabel toegepas word. Sonder `WITH CHECK OPTION` kan 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`/`authenticated` toegestaan.
- 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):
```bash
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/DELETE` op 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 OPTION` en aanvullende RLS op base tables om te verseker dat slegs toegelate rye geskryf/gewyzig kan word.
- In Supabase, vermy om `anon`/`authenticated` enige write privileges op views te gee tensy jy end-to-end gedrag met toetse geverifieer het.
Detection tip:
- From `anon` and an `authenticated` test user, probeer alle CRUD-operations teen elke blootgestelde table/view. Enige suksesvolle write waar jy weiering verwag het, dui op `misconfiguration`.
### 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):
```bash
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):
```bash
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):
```bash
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:
```bash
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:
```bash
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 `anon` en 'n minimaal `authenticated` gebruiker 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 (standaard), vereistes (geen standaard) en om die gebruik van gelekte wagwoorde te verbied.\
Dit word aanbeveel om die **vereistes te verbeter aangesien die standaard een swak is**.
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**.
- Gebruiker Sessies: Dit is moontlik om te configureer hoe gebruiker sessies werk (tydoue, 1 sessie per gebruiker...)
- Bot en Misbruik Beskerming: Dit is moontlik om Captcha in te skakel.
- 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
### SMTP-instellings
Dit is moontlik om 'n SMTP in te stel om e-posse te stuur.
### Gevorderde Instellings
### Gevorderde instellings
- Stel vervaldatum in vir toegangstokens (3600 standaard)
- Stel in om potensieel gecompromitteerde verfris tokens te detecteer en te herroep en tydoue
- MFA: Dui aan hoeveel MFA faktore op een slag per gebruiker geregistreer kan word (10 standaard)
- Maksimum Direkte Databasis Verbindinge: Maksimum aantal verbindings wat gebruik word om te verifieer (10 standaard)
- Maksimum Versoek Duur: Maksimum tyd wat toegelaat word vir 'n Auth versoek om te duur (10s standaard)
- 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)
## Berging
## Stoor
> [!TIP]
> Supabase laat **toe om lêers te stoor** en dit oor 'n URL beskikbaar te stel (dit gebruik S3 emmers).
> Supabase laat toe om **lêers te stoor** en dit via 'n URL toeganklik te maak (dit gebruik S3 buckets).
- Stel die opgelaaide lêergrootte limiet in (standaard is 50MB)
- Die S3 verbinding word gegee met 'n URL soos: `https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3`
- Dit is moontlik om **S3 toegangssleutel** aan te vra wat gevorm word deur 'n `access key ID` (bv. `a37d96544d82ba90057e0e06131d0a7b`) en 'n `secret access key` (bv. `58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628`)
- 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 'n `secret access key` (bv. `58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628`)
## Edge Funksies
## Edge Functions
Dit is moontlik om **geheime** in supabase te stoor wat ook **toeganklik sal wees deur edge funksies** (hulle kan van die web geskep en verwyder word, maar dit is nie moontlik om hul waarde direk te benader nie).
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, getDiscloseds Supabase Misconfig, and the LHE Squad (Ep. 133) YouTube](https://youtu.be/NI-eXMlXma4)
- [Critical Thinking Podcast Episode 133 page](https://www.criticalthinkingpodcast.io/episode-133-building-hacker-communities-bug-bounty-village-getdisclosed-and-the-lhe-squad/)
- [Supabase: Row Level Security (RLS)](https://supabase.com/docs/guides/auth/row-level-security)
- [PostgreSQL: Row Security Policies](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
- [PostgreSQL: CREATE VIEW (security_invoker, check option)](https://www.postgresql.org/docs/current/sql-createview.html)
- [PostgREST: OpenAPI documentation](https://postgrest.org/en/stable/references/api.html#openapi-documentation)
{{#include ../banners/hacktricks-training.md}}