---
title: "Lovable-App absichern: 12 Prüfungen, dazu 8 neue"
description: "Sicherheits-Checkliste für Lovable-Apps auf Supabase aus einer Kunden-App: zu jeder Prüfung die Abfrage oder der Test, dazu 8 Lücken, die Listen übersehen."
url: "https://madsalt.tech/de/blog/lovable-app-security-checklist/"
author: "Denys Zaichenko"
language: "de"
published: 2026-10-18
updated: 2026-10-25
---

# Lovable-App absichern: 12 Prüfungen, dazu 8 neue

Kurz gesagt

Eine Lovable-App ist so sicher wie ihre Supabase-Datenbank, und "RLS ist an" beweist sehr wenig. Testen Sie mit zwei Nutzern in zwei Firmen, halten Sie Rollen aus den Nutzer-Metadaten heraus, halten Sie den Secret Key aus dem Browser heraus und prüfen Sie Grants, Views, Storage, Funktionen und Rate Limits einzeln, denn jedes davon umgeht Ihre Policies auf eigene Weise. Unten steht die Liste, die ich durchgehe, der Prompt zum Einfügen in Lovable oder Claude und acht Prüfungen, die ich ergänzt habe, nachdem mir die Lovable-App eines Kunden gezeigt hat, was die ersten zwölf übersehen.

Ich bin Denys, Full-Stack- und KI-Entwickler. In diesem Monat habe ich die mit Lovable gebaute App eines Kunden repariert. Alles lief wie üblich auf Supabase, und es gab so viele Sicherheitskorrekturen, dass die App fast aus ihnen bestand. Das ist die Liste, die ich jetzt bei jedem Lovable- oder Supabase-Projekt durchgehe, bevor ich Kundendaten als geschützt bezeichne.

## Wie sicher ist Lovable? Die bisherigen Sicherheitsvorfälle

Die Plattform baut und hostet Ihre App, doch ob die App sicher ist, hängt vor allem von der Supabase-Datenbank dahinter ab, weil die App diese Datenbank direkt aus dem Browser liest und beschreibt. Die öffentliche Aktenlage zeigt beide Arten von Problemen:

| Wann                        | Was passiert ist                                                                                                                                                                                                                         | Quelle                                                                                                                                                |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| März 2025                   | CVE-2025-48757: Ein Scan von 1.645 Lovable-Showcase-Apps fand in 170 davon 303 Endpunkte, die jedem mit dem öffentlichen Key Daten lieferten, weil RLS fehlte oder zu lax war                                                            | [Matt Palmers Offenlegung](https://mattpalmer.io/posts/2025/05/statement-on-CVE-2025-48757/), Mai 2025                                                |
| Februar 2026                | Eine auf Lovable gehostete App legte 18.697 Nutzerdatensätze offen; eine Zugriffsprüfung in ihren Funktionen ließ anonyme Besucher ein und sperrte angemeldete Nutzer aus. Lovable erklärte, ein Teil des Codes stamme nicht von Lovable | [The Register](https://www.theregister.com/software/2026/02/27/ai-built-app-on-lovable-exposed-18k-users-researcher-claims/5038511), 27. Februar 2026 |
| 3. Februar – 20. April 2026 | Eine Regression der Plattform ließ andere Lovable-Nutzer den Chatverlauf und den Quellcode öffentlicher Projekte lesen                                                                                                                   | [Lovables Vorfallsbericht](https://lovable.dev/blog/our-response-to-the-april-2026-incident), 22. April 2026                                          |

Die ersten beiden sind Lücken auf App-Ebene, wie sie die Prüfungen unten finden. Die dritte lag bei Lovable selbst und wurde von Lovable behoben; Ihr Teil ist, Keys aus Chats und Code herauszuhalten (Prüfung 3) und alle zu rotieren, die dort standen. Lovable führt vor dem Veröffentlichen einen Sicherheitsscan aus, doch auf sein Ergebnis zu reagieren liegt bei Ihnen, und als die CVE veröffentlicht wurde, prüfte dieser Scan, ob eine Policy existierte, nicht, ob sie korrekt war. "Wie sicher ist Lovable?" läuft also darauf hinaus, ob Ihre Datenbank die Prüfungen unten besteht.

## Warum reicht "RLS ist an" in einer Lovable-App nicht?

Eine Lovable-App spricht direkt aus dem Browser mit der Datenbank. Dazwischen liegt kein eigenes Backend: Die Seite ruft die Supabase Data API mit einem öffentlichen Key auf, und Postgres entscheidet, was zurückkommt (welche Schemas diese API ausliefert, ist eine eigene Einstellung, beschrieben unter [Supabase Exposed Schemas](https://madsalt.tech/de/notes/supabase-exposed-schemas/)). Jede Regel, die Kundendaten schützt, muss also in der Datenbank liegen, und die Datenbank hat mehrere Türen.

Row Level Security ist eine davon. Grants entscheiden, ob eine Rolle eine Tabelle überhaupt anfassen darf, Policies entscheiden, welche Zeilen, und drei Dinge überspringen Policies komplett: der Secret Key, Views, die ohne `security_invoker` angelegt wurden, und `SECURITY DEFINER`-Funktionen. Das ist nicht hypothetisch. Lovables eigener [Sicherheitsleitfaden](https://docs.lovable.dev/tips-tricks/security-best-practices) verlangt, die von ihm eingerichteten RLS-Policies zu prüfen, und [CVE-2025-48757](https://www.upguard.com/blog/everything-everywhere-systemic-data-exposure-in-supabase-apps) oben zeigt, was passiert, wenn das niemand tut.

![Vier Wege zu Ihren Daten. Nur der erste wird von Ihren RLS-Policies geprüft. Normale Anfrage: Browser → Grant → RLS-Policy → Eigene Zeilen; Secret Key in einer Edge Function: Browser → Edge Function → Secret Key → Jede Zeile; View ohne security_invoker: Browser → View → Rechte des Besitzers → Jede Zeile; SECURITY DEFINER-Funktion: Browser → RPC → Rechte des Besitzers → Jede Zeile.](https://madsalt.tech/charts/de/lovable-app-security-checklist-paths.svg)

*Abbildung 1. Nur der erste Weg wird von Ihren Policies geprüft. Die anderen drei laufen mit Rechten, die RLS überspringen. Quelle: Supabase-Dokumentation zu RLS und zur Absicherung der API, Oktober 2026.*

## Der Prompt: in Lovable oder Claude einfügen

Sie können ihn unverändert einfügen. Prüfen Sie das Ergebnis danach selbst: KI sagt gern "fertig", wenn es das nicht ist, und ein Prompt, der einen Fehler verschwinden lässt, kann das tun, indem er den Zugriff erweitert.

```text
Prüfe dieses Projekt auf Sicherheit, behebe, was du findest, und sag mir, was du geändert hast:

1. Teste mit zwei Nutzern in zwei Firmen. Nutzer A versucht, Datensätze von B per ID zu lesen, zu ändern und zu löschen, über die API, die Suche und Exporte. Alles muss scheitern.
2. RLS auf jeder Tabelle, Policies prüfen den Besitzer der Zeile oder die Firma. "Angemeldet" reicht nicht.
3. Service-Role-Key nie im Frontend. Edge Functions, die ihn nutzen, prüfen den Nutzer und filtern selbst nach Firma, der Key überspringt RLS.
4. Rollen, Tarif, Firmen-ID nie aus den Nutzer-Metadaten, Nutzer können sie ändern. Lege sie in einer Tabelle ab, die nur der Server beschreibt.
5. Wenn eine Anfrage zwei IDs sendet (Projekt + Aufgabe), prüfe, dass die Aufgabe zu diesem Projekt gehört.
6. Entziehe anon und authenticated alle Tabellenrechte, vergib nur zurück, was die Policies brauchen. RLS stoppt TRUNCATE nicht. Jede Migration, die eine Tabelle anlegt, enthält ihr GRANT: Ab dem 30. Oktober 2026 vergibt Supabase neue Tabellen nicht mehr automatisch, und die App bekommt den Fehler 42501.
7. Alle Views mit security_invoker = true, sonst überspringen sie RLS.
8. Storage-Buckets: Nutzer lesen und schreiben nur ihre eigenen Dateien, keine öffentlichen Buckets für private Daten.
9. SECURITY DEFINER-Funktionen: NULL muss "verweigern" heißen, nicht "erlauben".
10. Rate Limits für Login, Registrierung, Zurücksetzen, OTP, in der DB gespeichert, nicht im Arbeitsspeicher.
11. Validiere alle Eingaben auf dem Server.
12. Führe den Supabase Security Advisor aus, behebe jede Warnung.
```

## Die 12 Prüfungen und wie Sie jede beweisen

### 1. Zwei Nutzer in zwei Firmen

Legen Sie Nutzer A in Firma 1 und Nutzer B in Firma 2 an, jeweils mit ein paar Datensätzen. Melden Sie sich als A an und versuchen Sie, Datensätze von B per ID zu lesen, zu ändern und zu löschen, über die API, über die Suche und über jeden Export. Jeder Versuch muss nichts oder einen Fehler liefern. Das ist der eine Test, der das meiste des Folgenden abfängt, weil er prüft, was der Angreifer tut, nicht was Sie geschrieben haben.

![Zwei Nutzer, zwei Firmen. Nutzer A aus Firma 1 greift nach Datensätzen von Firma 2. Jeder Weg muss nichts liefern. Per ID über die API: Nutzer A → ID von B → Lesen, ändern, löschen → 0 Zeilen oder Fehler; Über die Suche: Nutzer A → Text von B suchen → Treffer → Keine B-Zeilen; Über einen Export: Nutzer A → Export → Datei → Keine B-Zeilen.](https://madsalt.tech/charts/de/lovable-app-security-checklist-test.svg)

*Abbildung 2. Der Zwei-Firmen-Test. Bestanden heißt: Kein Weg liefert etwas von Firma 2.*

Fügen Sie einen dritten Nutzer hinzu, der zu beiden Firmen gehört. Eine Policy der Form "der Aufrufer ist Mitglied der Firma der Zeile" lässt diesen Nutzer die Zeilen von Firma 2 lesen, während er in Firma 1 arbeitet. In einer anderen Supabase-App lieferte meine Probe mit so einem Nutzer das Dokument der anderen Firma, bis die Abfrage auch nach der Firma der Anfrage filterte. Das habe ich aufgeschrieben als [einen Nutzer in zwei Orgs, den RLS nicht isolierte](https://madsalt.tech/de/notes/supabase-rls-user-in-two-organizations/).

### 2. RLS auf jeder Tabelle, auf Besitzer oder Firma begrenzt

`auth.uid() is not null` bedeutet "jeder angemeldete Nutzer", und auf einer öffentlichen Registrierungsseite heißt das: jeder. Jede Policy vergleicht den Besitzer oder die Firma der Zeile mit dem Aufrufer. So listen Sie die Tabellen auf, bei denen RLS noch aus ist:

```sql
select c.relname
from pg_class c join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public' and c.relkind in ('r', 'p') and not c.relrowsecurity;
```

### 3. Der Secret Key nie im Frontend

Der Service-Role-Key und der neuere `sb_secret_`-Key umgehen jede Policy. Durchsuchen Sie das gebaute JavaScript nach beiden und rotieren Sie jeden Key, der je ausgeliefert wurde. Edge Functions, die ihn nutzen, müssen selbst prüfen, wer der Nutzer ist, und selbst nach Firma filtern, denn mit diesem Key tut es sonst nichts.

### 4. Rollen, Tarif und Firmen-ID nie aus den Nutzer-Metadaten

`raw_user_meta_data` ist, was der Client an `signUp` geschickt hat, und Nutzer können es später ändern. In einer anderen App las der Trigger für neue Nutzer die eingeladene Rolle daraus, sodass sich jeder, der sich registrierte, mit der Owner-Rolle selbst zum Owner machen konnte. Halten Sie Rollen, Tarife und Firmen-IDs in einer Tabelle, die nur der Server beschreibt, oder in `app_metadata`. Die ganze Geschichte: [eine Rolle aus den Metadaten der Registrierung](https://madsalt.tech/de/notes/supabase-raw-user-meta-data-role/).

### 5. Zwei IDs in einer Anfrage: prüfen, dass sie zusammengehören

Trägt eine Anfrage eine Projekt-ID und eine Aufgaben-ID, reicht es nicht, das Projekt zu autorisieren. Ein Nutzer mit Rechten auf Projekt A sendet A plus eine Abschnitts-ID aus Projekt B, und die Zeile landet in B. RLS fängt das nicht ab, weil der Insert die eigene Projekt-ID des Angreifers einträgt, und genau die prüft die Policy. Prüfen Sie vor dem Schreiben, dass das Kind zum Elternobjekt gehört.

### 6. Grants: erst entziehen, dann nur das Nötige zurückgeben

Grants und Policies sind zwei getrennte Ebenen. Policies hinzuzufügen nimmt keinen Grant zurück, weshalb der [RLS-Leitfaden](https://supabase.com/docs/guides/database/postgres/row-level-security) von Supabase rät, ausdrücklich zu entziehen und zurückzugeben. In einem anderen Projekt hatte das Image `supabase/postgres` 17.6.1 `anon` und `authenticated` auf jeder Tabelle in `public` TRUNCATE, REFERENCES, TRIGGER und MAINTAIN gegeben, und auf TRUNCATE wirkt keine Policy. Die Data API hat keinen TRUNCATE-Endpunkt, es ist also kein Löschen mit einer einzigen Anfrage, aber keine Client-Rolle braucht das Recht, und jede Funktion, die SQL als diese Rolle ausführt, erbt es.

```sql
revoke all on public.orders from anon, authenticated;
grant select, insert, update on public.orders to authenticated;

select grantee, table_name, privilege_type
from information_schema.role_table_grants
where table_schema = 'public' and grantee in ('anon', 'authenticated')
order by table_name;
```

Ein Datum ändert diese Prüfung. Supabase [vergibt neue Tabellen nicht mehr automatisch](https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically): für neue Projekte seit dem 30. Mai 2026 und für alle bestehenden Projekte ab dem 30. Oktober 2026, auch die, die Lovable angelegt hat. Danach ist eine Tabelle, die Lovable oder eine Migration ohne ausdrückliches `GRANT` anlegt, für die App unsichtbar: Die Anfrage scheitert mit 42501, und die Funktion, die die Tabelle nutzt, geht kaputt. Jede Migration, die eine Tabelle anlegt, bringt ihre Grants deshalb jetzt mit, neben `enable row level security` und den Policies.

Zwei Dinge bleiben gleich. Bestehende Tabellen behalten ihre Grants, das Entziehen des Unnötigen bleibt also Ihre Aufgabe. Und die Änderung nimmt nur select, insert, update und delete zurück: Im Lovable-Projekt kamen neue Tabellen mit den neuen Defaults weiterhin mit TRUNCATE, REFERENCES, TRIGGER und MAINTAIN für `anon` und `authenticated`. Erst alles entziehen, dann vergeben, bleibt die sichere Reihenfolge.

### 7. Jede View mit `security_invoker = true`

Eine View läuft mit den Rechten ihres Besitzers, und in Supabase ist der Besitzer meist `postgres`. Eine View über eine geschützte Tabelle gibt deshalb jede Zeile heraus, die die Policies zurückhalten. Ab Postgres 15:

```sql
alter view public.customer_summary set (security_invoker = true);
```

### 8. Storage: nur eigene Dateien, kein öffentlicher Bucket für private Daten

Ein öffentlicher Bucket liefert jede Datei an jeden, der die URL hat. Private Dateien gehören in einen privaten Bucket mit Policies auf `storage.objects`, die Besitzer oder Firma prüfen, meist anhand des ersten Ordners im Pfad. Zählen Sie nach dem Umzug eines Projekts die aktiven Storage-Policies: In einer App schlug nach einem Umzug jeder Upload fehl, weil die Policy-Migration nie lief und die Tabelle RLS an hatte, aber null Policies.

### 9. SECURITY DEFINER-Funktionen: NULL heißt verweigern

In PL/pgSQL löst `if not (has_permission or assignee_id = auth.uid())` keine Exception aus, wenn `assignee_id` null ist: Die ganze Bedingung ist null, und `if` überspringt sie. Derselbe Ausdruck ist in einer Policy sicher, die null als Ablehnung behandelt. In einer App ließ das eine Rolle mit ausgeschalteten Rechten auf alle 3683 Aufgaben zugreifen, weil keine eine zuständige Person hatte. Schließen Sie die Bedingung in `coalesce(…, false)` ein. Details: [NULL im PL/pgSQL-IF NOT: Prüfung übersprungen](https://madsalt.tech/de/notes/plpgsql-if-not-null-fails-open/).

### 10. Rate Limits in der Datenbank speichern

Begrenzen Sie Login, Registrierung, Passwort-Reset und OTP und halten Sie den Zähler in Postgres. In der Lovable-App lagen die Limits in einer Variablen in der Edge Function. Ich habe das gehostete Projekt am 17. Oktober 2026 geprüft: Jede Anfrage lief in einem frischen Isolate, der Zähler im Speicher stand also immer auf 1 und das Limit konnte nie greifen. Das lokale `supabase functions serve` verwendet das Isolate wieder, deshalb bestand derselbe Code jeden lokalen Test.

![Wo der Zähler liegt, entscheidet. Rate Limit in einer gehosteten Supabase Edge Function. Zähler im Speicher der Funktion: Anfrage → Neues Isolate → Zähler = 1 → Nie begrenzt; Zähler in Postgres: Anfrage → claim_rate_limit → Gemeinsame Zeile → 429 am Limit.](https://madsalt.tech/charts/de/lovable-app-security-checklist-ratelimit.svg)

*Abbildung 3. Meine Probe einer gehosteten Supabase Edge Function, 17. Oktober 2026: Jede Anfrage startete ein frisches Isolate.*

Der Schlüssel zählt so viel wie der Speicher. Auf der gehosteten Plattform ist der letzte `X-Forwarded-For`-Hop Supabases eigener Proxy; wer danach bucketet, steckt alle Aufrufer in einen Bucket, und `x-client-ip` setzt der Client. In meiner Probe trug `cf-connecting-ip` den echten Client. Die Lösung war eine `SECURITY DEFINER`-Funktion `claim_rate_limit(bucket, key, max, window)`, die nur die Service Role ausführen darf, per Advisory Lock serialisiert und mit einem Hash der IP oder Nutzer-ID statt des Rohwerts.

### 11. Alle Eingaben auf dem Server validieren

Was auch immer das Formular prüft: Die API nimmt alles an, was der Client sendet. Längen, Formate, Enums und Besitz werden in der Datenbank (Constraints, Trigger) oder in der Edge Function geprüft, nie nur in React.

### 12. Der Supabase Security Advisor, jede Warnung

Öffnen Sie Advisors, dann Security Advisor, und beheben Sie jeden Befund. Er meldet Tabellen ohne RLS, Views, die RLS überspringen, Policies, die Nutzer-Metadaten lesen, großzügige `using (true)`-Policies und Funktionen mit veränderlichem `search_path`. Die Prüfungen 1, 5, 9 und 10 sieht er nicht, denn dabei geht es um Logik, nicht um Konfiguration.

## Was hat mich die Lovable-App gelehrt, das die 12 übersehen?

Das stammt aus der App des Kunden und ihren Reviews. Keines davon zeigt ein Scanner.

1. **Felder, die der Client nicht setzen darf.** Der Client schickte `status: 'approved'` selbst und umging so die Moderation. Eine UPDATE-Policy, deren `with check` lockerer ist als ihr `using`, lässt einen Nutzer außerdem eine Zeile zu einem anderen Besitzer verschieben. Eine Policy kann keinen Wert berechnen, deshalb leitet ein `BEFORE INSERT OR UPDATE`-Trigger `status`, Rolle, Preis und Firma aus den Daten des Servers neu ab und ignoriert, was der Client gesendet hat.
2. **Jeder Schreibweg, nicht nur der Haupt-Insert.** Nachdem der Haupt-Insert repariert war, steckte dieselbe Umgehung in Anhängen, Kommentaren, dem Wiederherstellen eines gelöscht markierten Eintrags und in Zählern. Listen Sie jeden Schreiber einer geschützten Spalte auf, bevor Sie den ersten reparieren.
3. **Allow-Listen, keine Deny-Listen.** Gefälschte Datensätze brauchten fünf Review-Runden, weil jede Korrektur eine Kombination blockierte und eine Schwester offen ließ. Ein Trigger, der nur die aufgeführten Kombinationen aus Typ und Status erlaubt, schloss die ganze Klasse auf einmal.
4. **Funktionen sind auch eine API.** Jede Funktion in `public` ist über `/rpc` für jede Rolle mit EXECUTE aufrufbar, und RLS gilt nicht für Funktionen. Geben Sie jeder `SECURITY DEFINER`-Funktion `set search_path = ''`, entziehen Sie EXECUTE für `public`, `anon` und `authenticated` und vergeben Sie es nur an die Rolle, die es braucht.
5. **EXECUTE zu entziehen kann öffentliche Seiten kaputt machen.** Postgres prüft EXECUTE für jede Funktion jeder Policy, die für die Rolle gilt, selbst in einem Zweig, der nie läuft. Nachdem `anon` EXECUTE auf `is_admin()` verloren hatte, scheiterte jedes anonyme Lesen mit 42501. Policies nur für Admins gehören `to authenticated`, und öffentliche Lesezugriffe bekommen eine eigene Policy ohne den Admin-Zweig.
6. **Registrierung mit eingeschalteter E-Mail-Bestätigung.** Bei eingeschalteter Bestätigung liefert `signUp` keine Session, sodass jeder Profil-Schreibvorgang direkt danach als `anon` läuft und stillschweigend nichts schreibt. Lovable-Projekte haben oft Auto-Confirm an, was den Fehler verdeckt. Übergeben Sie die Felder in `signUp({ options: { data } })`, lassen Sie den Trigger für neue Nutzer sie prüfen und schreiben, und behandeln Sie diese Metadaten als nicht vertrauenswürdig (Prüfung 4).
7. **Tests, die aus dem falschen Grund bestehen.** Der lokale Stack und das gehostete Projekt hatten unterschiedliche Default-Rechte, also bestand "anon kann nicht einfügen" lokal, weil der Grant fehlte, nicht weil RLS wirkte. Ein negativer Test bedeutet nur etwas, wenn der positive Grant existiert. Vergleichen Sie `pg_default_acl` lokal und in der Produktion.
8. **Die Live-Datenbank, nicht die Migrationsdateien.** Vergleichen Sie nach einer Migration oder einem Projektumzug, was tatsächlich live ist: `pg_policies`, `pg_get_functiondef` für jede Schutzfunktion und die Grants von oben. In einer anderen App kopierte eine neue Migration einen alten Funktionskörper und machte leise eine spätere Korrektur rückgängig.

## Ist eine Lovable-Cloud-App DSGVO-konform?

Lovable macht eine App weder DSGVO-konform noch nicht konform; das entscheidet, was die App mit personenbezogenen Daten tut, und ein Security-Review beantwortet das nicht. Das sind die sechs Lücken, die ich in einer Lovable-Cloud-App prüfe, jeweils mit der Lösung:

1. **Jeden Auftragsverarbeiter auflisten.** Lovable Cloud betreibt Datenbank, Auth, Storage und Funktionen auf Supabase, Lovable hostet die Seite und kann die Anmelde-E-Mails versenden, und das Lovable AI Gateway reicht Text an einen Modellanbieter weiter. Ergänzen Sie jeden E-Mail-, KI- oder Scraping-Dienst, den Ihre Funktionen aufrufen. Jeder, der personenbezogene Daten erhält, braucht einen Auftragsverarbeitungsvertrag (AVV), ein Anbieter außerhalb der EU zusätzlich eine Grundlage für die Übermittlung. Die Hosting-Region steht nirgends im Code, also fragen Sie danach.
2. **Einen Nutzer mit Inhalten löschen.** Fremdschlüssel aus dem, was dieser Nutzer geschrieben hat, können das Löschen blockieren, und dann lässt sich ein Löschantrag nicht erfüllen. Lassen Sie diese Schlüssel kaskadieren oder auf NULL setzen, ergänzen Sie einen Lösch-Trigger, der auch die E-Mail-Logs und Login-Tokens des Nutzers entfernt, und behalten Sie einen Datenbanktest, der einen solchen Nutzer löscht.
3. **Eine Speicherfrist festlegen.** E-Mail-Logs, Aufruf-Tracking, Warteschlangen fehlgeschlagener E-Mails und weich gelöschte Zeilen behalten personenbezogene Daten oft ohne Enddatum. Ein geplanter Job, der weich gelöschte Zeilen nach einer festen Frist endgültig löscht und ihre Dateien entfernt, schließt das meiste davon.
4. **E-Mail-Tracking nur mit Einwilligung.** Öffnungen und Klicks pro Empfänger zu erfassen braucht nach den ePrivacy-Regeln eine Einwilligung: ein Einwilligungs-Flag, standardmäßig aus, mit einem Zeitstempel, den der Server setzt, nicht der Client.
5. **Adressen aus den Funktions-Logs heraushalten.** Logs von Edge Functions werden nicht bereinigt, ein `console.log` mit einer Empfängeradresse behält diese Adresse also dort. Loggen Sie IDs und Anzahlen.
6. **E-Mail-Bestätigung einschalten.** Mit Auto-Confirm kann sich jeder mit einer Adresse registrieren, die ihm nicht gehört, und so die Adresse einer echten Person in die App bringen. Punkt 6 in der Liste oben deckt die Seite der Registrierung ab.

So prüfen Sie Ihre eigene App: Suchen Sie in den Funktionen nach API-Schlüsseln, um die Dienste aufzulisten, löschen Sie einen Testnutzer mit Inhalten, durchsuchen Sie die Funktions-Logs nach `@` und fordern Sie von jedem Anbieter den AVV an. Das ist keine Rechtsberatung.

## Wie verhindern Sie, dass es zurückkommt?

Jede Prüfung oben ist eine Abfrage oder ein Test, halten Sie sie also im Repo und führen Sie sie vor jedem Deploy aus. Die [pgTAP-Tests](https://supabase.com/docs/guides/database/extensions/pgtap) von Supabase decken Grants, Policies und Funktionen ab; der Zwei-Firmen-Test gehört daneben. Hat Ihre App Rollen und eine Rechte-Seite, reicht auch ein Test je Policy nicht: Ich beweise jedes Rechte-Kästchen an einer Kopie der Produktion, beschrieben in [Supabase RLS testen](https://madsalt.tech/de/blog/how-to-test-supabase-rls/), wo sich zeigte, dass 30 von 87 Kästchen nichts bewirkten. Der kostenlose [Supabase Sicherheitscheck](https://madsalt.tech/de/tools/supabase-security-check/) prüft Rollen, Grants, Policies und Auth-Einstellungen eines Projekts gegen 46 Regeln der OWASP Top 10:2025, nutzen Sie ihn also für den ersten Durchgang; der Zwei-Firmen-Test und alles, was Ihre Oberfläche betrifft, bleiben manuell.

Was diese Liste nicht abdeckt: Zahlungen und Webhooks, Secrets in Ihrer Git-Historie, Security-Header beim Hoster, Backups. Sie sind wichtig, aber eine andere Checkliste.

Wenn Sie eine Lovable- oder Supabase-App geerbt haben und nicht sicher sind, welche dieser Prüfungen sie besteht, beginnt eine [Projektrettung](https://madsalt.tech/de/services/project-rescue/) mit diesem Audit. Die [Fallstudie zur Zeiterfassung für eine Wirtschaftsprüfungsgesellschaft](https://madsalt.tech/de/work/audit-firm-time-tracking/) zeigt, wie die Rollenprüfungen in einer Produktions-App aussehen.

Eine Lücke gefunden, die diese Liste übersieht?

Ich würde sie gern hören. Gern tausche ich mich darüber aus, wie man Lovable- und Supabase-Apps absichert.

[Kontakt aufnehmen](https://madsalt.tech/de/#contact)
