Supabase Ασφάλεια

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Βασικές Πληροφορίες

Σύμφωνα με την landing page: Το Supabase είναι μια open source εναλλακτική του Firebase. Ξεκινήστε το project σας με μια Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, και Vector embeddings.

Υποτομέας

Βασικά, όταν δημιουργείται ένα project, ο χρήστης θα λάβει ένα supabase.co subdomain όπως: jnanozjdybtpqgcwhdiz.supabase.co

Ρύθμιση βάσης δεδομένων

Tip

Αυτά τα δεδομένα είναι προσβάσιμα από έναν σύνδεσμο όπως https://supabase.com/dashboard/project/<project-id>/settings/database

Αυτή η database θα αναπτυχθεί σε κάποια AWS region, και για να συνδεθεί κάποιος σε αυτήν είναι δυνατό να γίνει σύνδεση στο: postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres (αυτό δημιουργήθηκε σε us-west-1).
Το password είναι ένα password που όρισε ο χρήστης προηγουμένως.

Επομένως, δεδομένου ότι ο subdomain είναι γνωστός και χρησιμοποιείται ως username και οι AWS regions είναι περιορισμένοι, μπορεί να είναι δυνατό να προσπαθήσει κανείς να brute force the password.

Αυτό το τμήμα περιέχει επίσης επιλογές για:

  • 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

Tip

Αυτά τα δεδομένα είναι προσβάσιμα από έναν σύνδεσμο όπως https://supabase.com/dashboard/project/<project-id>/settings/api

Το URL για πρόσβαση στο supabase API του project σας θα είναι κάτι σαν: https://jnanozjdybtpqgcwhdiz.supabase.co.

anon api keys

Θα δημιουργηθεί επίσης ένα anon API key (role: "anon"), όπως: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk που η εφαρμογή θα χρειαστεί για να επικοινωνήσει με το API που παρουσιάζεται στο παράδειγμα μας.

Είναι δυνατό να βρείτε το API REST για να επικοινωνήσετε με αυτό το API στα docs, αλλά τα πιο ενδιαφέροντα endpoints θα ήταν:

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>Σύνδεση (/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>

Έτσι, κάθε φορά που εντοπίζετε έναν client που χρησιμοποιεί supabase με τον υποτομέα που του έχει παραχωρηθεί (είναι πιθανό ένας υποτομέας της εταιρείας να έχει CNAME πάνω από τον supabase υποτομέα τους), μπορείτε να δοκιμάσετε να **δημιουργήσετε νέο λογαριασμό στην πλατφόρμα χρησιμοποιώντας το supabase API**.

### μυστικό / service_role API κλειδιά

Ένα μυστικό API key θα δημιουργηθεί επίσης με **`role: "service_role"`**. Αυτό το API key πρέπει να παραμείνει μυστικό γιατί θα μπορεί να παρακάμψει το **Row Level Security**.

Το API key μοιάζει με το εξής: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`

### JWT Secret

Ένα **JWT Secret** θα δημιουργηθεί επίσης ώστε η εφαρμογή να μπορεί να **δημιουργεί και να υπογράφει προσαρμοσμένα JWT tokens**.

## Authentication

### Signups

> [!TIP]
> Από προεπιλογή supabase θα επιτρέπει σε **νέους χρήστες να δημιουργούν λογαριασμούς** στο project σας χρησιμοποιώντας τα προαναφερθέντα API endpoints.

Ωστόσο, αυτοί οι νέοι λογαριασμοί, από προεπιλογή, **θα χρειαστεί να επιβεβαιώσουν το email τους** για να μπορούν να κάνουν login στον λογαριασμό. Είναι δυνατή η ενεργοποίηση του **"Allow anonymous sign-ins"** για να επιτρέψετε σε χρήστες να συνδέονται χωρίς να επαληθεύουν το email τους. Αυτό μπορεί να δώσει πρόσβαση σε **μη αναμενόμενα δεδομένα** (λαμβάνουν τους ρόλους `public` και `authenticated`).\
Αυτό είναι πολύ κακή ιδέα γιατί η supabase χρεώνει ανά ενεργό χρήστη, οπότε άνθρωποι θα μπορούσαν να δημιουργούν χρήστες και να κάνουν login και η supabase θα χρεώσει για αυτούς:

<figure><img src="../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>

#### Auth: Server-side signup enforcement

Το να κρύψετε το κουμπί signup στο frontend δεν είναι αρκετό. Αν ο **Auth server εξακολουθεί να επιτρέπει signups**, ένας attacker μπορεί να καλέσει απευθείας το API με το δημόσιο `anon` key και να δημιουργήσει αυθαίρετους χρήστες.

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

Αναμενόμενη ενίσχυση:

  • Απενεργοποιήστε τις εγγραφές email/password στο Dashboard: Authentication → Providers → Email → Disable sign ups (invite-only), ή ορίστε το αντίστοιχο GoTrue setting.
  • Επιβεβαιώστε ότι το API τώρα επιστρέφει 4xx στην προηγούμενη κλήση και δεν δημιουργείται νέος χρήστης.
  • Αν βασίζεστε σε invites ή SSO, βεβαιωθείτε ότι όλοι οι άλλοι providers είναι απενεργοποιημένοι εκτός αν χρειάζονται ρητά.

RLS και Views: Παράκαμψη εγγραφής μέσω PostgREST

Η χρήση ενός Postgres VIEW για να «κρύψετε» ευαίσθητες στήλες και η έκθεσή του μέσω PostgREST μπορεί να αλλάξει τον τρόπο αξιολόγησης των προνομίων. Στο PostgreSQL:

  • Ordinary views εκτελούνται με τα προνόμια του ιδιοκτήτη του view εξ ορισμού (definer semantics). Σε PG ≥15 μπορείτε να επιλέξετε security_invoker.
  • Row Level Security (RLS) εφαρμόζεται στους βασικούς πίνακες. Οι ιδιοκτήτες των πινάκων παρακάμπτουν το RLS εκτός αν έχει τεθεί το FORCE ROW LEVEL SECURITY στον πίνακα.
  • Τα updatable views μπορούν να δεχτούν INSERT/UPDATE/DELETE που στη συνέχεια εφαρμόζονται στον πίνακα βάσης. Χωρίς το WITH CHECK OPTION, οι εγγραφές που δεν ταιριάζουν με τη συνθήκη του view μπορεί να πετύχουν.

Πρότυπο κινδύνου που παρατηρήθηκε στην πράξη:

  • Ένα view με μειωμένες στήλες εκτίθεται μέσω Supabase REST και παραχωρείται σε anon/authenticated.
  • Το PostgREST επιτρέπει DML στο updatable view και η ενέργεια αξιολογείται με τα προνόμια του ιδιοκτήτη του view, παρακάμπτοντας ουσιαστικά τις προβλεπόμενες πολιτικές RLS στον πίνακα βάσης.
  • Αποτέλεσμα: clients με χαμηλά προνόμια μπορούν να μαζικά επεξεργαστούν σειρές (π.χ. profile bios/avatars) που δεν θα έπρεπε να μπορούν να τροποποιήσουν.

Ενδεικτική εγγραφή μέσω view (προσπάθεια από 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>"

Λίστα ελέγχου ενίσχυσης για views και RLS:

  • Προτιμήστε να εκθέτετε base tables με ρητά, least-privilege grants και ακριβείς πολιτικές RLS.
  • Αν πρέπει να εκθέσετε ένα view:
  • Κάντε το μη-ενημερώσιμο (π.χ., include expressions/joins) ή απαγορεύστε INSERT/UPDATE/DELETE στο view για όλους τους μη-έμπιστους ρόλους.
  • Εφαρμόστε ALTER VIEW <v> SET (security_invoker = on) ώστε να χρησιμοποιούνται τα προνόμια του invoker αντί του owner.
  • Στα base tables, χρησιμοποιήστε ALTER TABLE <t> FORCE ROW LEVEL SECURITY; ώστε ακόμη και οι owners να υπόκεινται σε RLS.
  • Εάν επιτρέπετε εγγραφές μέσω updatable view, προσθέστε WITH [LOCAL|CASCADED] CHECK OPTION και συμπληρωματικό RLS στα base tables για να εξασφαλίσετε ότι μόνο οι επιτρεπόμενες γραμμές μπορούν να γραφτούν/τροποποιηθούν.
  • Στο Supabase, αποφύγετε να δίνετε σε anon/authenticated δικαιώματα εγγραφής σε views εκτός αν έχετε επαληθεύσει το end-to-end behavior με tests.

Detection tip:

  • Από έναν test user anon και έναν authenticated, επιχειρήστε όλες τις CRUD ενέργειες εναντίον κάθε εκτεθειμένου table/view. Οποιαδήποτε επιτυχής εγγραφή όπου περιμένατε άρνηση υποδεικνύει κακή διαμόρφωση.

OpenAPI-driven CRUD probing από ρόλους anon/auth

Το PostgREST εκθέτει ένα OpenAPI έγγραφο που μπορείτε να χρησιμοποιήσετε για να απαριθμήσετε όλους τους REST πόρους και μετά να δοκιμάσετε αυτόματα τις επιτρεπόμενες ενέργειες από ρόλους με χαμηλά προνόμια.

Αποκτήστε το OpenAPI (λειτουργεί με το 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 (παραδείγματα):

  • Διάβασε μία γραμμή (αναμένουμε 401/403/200 ανάλογα με 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>"
  • Ελέγξτε ότι το UPDATE είναι αποκλεισμένο (χρησιμοποιήστε ένα ανύπαρκτο φίλτρο για να αποφύγετε την αλλοίωση των δεδομένων κατά τη δοκιμή):
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:

  • Αυτοματοποιήστε τις προηγούμενες probes για τόσο anon όσο και για έναν ελάχιστα authenticated χρήστη και ενσωματώστε τις στο CI για να εντοπίζετε regressions.
  • Θεωρείτε κάθε εκτεθειμένο table/view/function ως πρώτη-τάξης επιφάνεια. Μην υποθέτετε ότι μια view “κληρονομεί” την ίδια RLS στάση με τους βασικούς πίνακές της.

Passwords & sessions

It’s possible to indicate the minimum password length (by default), requirements (no by default) and disallow to use leaked passwords.
Συνιστάται να βελτιώσετε τις απαιτήσεις καθώς οι προεπιλεγμένες είναι αδύναμες.

  • User Sessions: Είναι δυνατό να διαμορφώσετε πώς λειτουργούν οι συνεδρίες χρηστών (timeouts, 1 session per user…)
  • Bot and Abuse Protection: Είναι δυνατό να ενεργοποιήσετε Captcha.

SMTP Settings

Είναι δυνατό να ορίσετε ένα SMTP για την αποστολή emails.

Advanced Settings

  • Ορίστε χρόνο λήξης για access tokens (3600 από προεπιλογή)
  • Ορίστε τον εντοπισμό και την ανάκληση πιθανώς compromised refresh tokens και timeout
  • MFA: Υποδείξτε πόσοι παράγοντες MFA μπορούν να εγγραφούν ταυτόχρονα ανά χρήστη (10 από προεπιλογή)
  • Max Direct Database Connections: Μέγιστος αριθμός συνδέσεων που χρησιμοποιούνται για auth (10 από προεπιλογή)
  • Max Request Duration: Μέγιστος χρόνος που επιτρέπεται για ένα Auth request (10s από προεπιλογή)

Storage

Tip

Supabase allows to store files and make them accesible over a URL (it uses S3 buckets).

  • Ορίστε το όριο μεγέθους αρχείου για upload (από προεπιλογή 50MB)
  • The S3 connection is given with a URL like: https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3
  • Είναι δυνατό να request S3 access key που αποτελούνται από ένα access key ID (π.χ. a37d96544d82ba90057e0e06131d0a7b) και ένα secret access key (π.χ. 58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628)

Edge Functions

Είναι δυνατό να αποθηκεύσετε secrets στο supabase τα οποία θα είναι προσβάσιμα από edge functions (μπορούν να δημιουργηθούν και να διαγραφούν από το web, αλλά δεν είναι δυνατό να προσπελάσετε την τιμή τους απευθείας).

References

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks