Beispiel-Report

So sieht ein vollständiger Report aus

Das hier ist ein erfundener Bericht einer Domain, die es nicht gibt — aber die Befunde sind die, die wir in echten Scans am häufigsten finden. Vollständig aufgeklappt, mit Fundstelle, Beweis und fertiger Anleitung. Genau das bekommst du nach der Freischaltung für deine eigene Domain.

Erfundene Daten. Die Domain beispiel-app.de existiert nicht — ein Beispielreport über eine echte fremde Seite wäre die Veröffentlichung ihrer Schwachstellen.

Sicherheitsbericht für

beispiel-app.de

Geprüft am 1. August 2026 · Wird automatisch gelöscht am 30. Oktober 2026

E

Sicherheitsnote

Dringend beheben

  • 2

    kritisch

  • 1

    hoch

  • 2

    mittel

  • 1

    gering

  • 1

    Hinweis

  • 1× Zugangsdaten
  • 1× Datenbank
  • 1× Mitgelieferte Dateien
  • 2× Auslieferung
  • 1× E-Mail-Zustellung
  • 1× Erkannter Aufbau

7 Befunde in 6 Bereichen

kritischZugangsdaten

OpenAI-Schlüssel im ausgelieferten JavaScript

Ein OpenAI-Schlüssel steht im Klartext in deinem Frontend-Bundle. Jeder Besucher kann ihn auslesen; automatisierte Bots durchsuchen öffentliche Bundles gezielt danach. Der Schlüssel gilt als kompromittiert, sobald er einmal ausgeliefert wurde — auch wenn du das Bundle jetzt austauschst.

Fundstelle:
/assets/index-Bq7fK2mP.js, Zeile 1842
Auszug:
const openai=new OpenAI({apiKey:"sk-proj-4f8a2…",dangerouslyAllowBrowser:true})

So behebst du es

Widerrufe den Schlüssel sofort unter platform.openai.com/api-keys — nicht später, der alte ist unwiederbringlich öffentlich.

Danach: Der Aufruf gehört auf den Server, nicht in den Browser. Lege eine eigene Route an (z. B. eine Edge Function oder /api/chat), die den Schlüssel serverseitig hält und die Anfrage weiterreicht. Das Frontend ruft nur noch deine eigene Route auf.

`dangerouslyAllowBrowser: true` ist der Hinweis des SDK selbst, dass dieser Weg nicht vorgesehen ist.
kritischDatenbank

Supabase-Tabelle „profiles" ohne Row Level Security lesbar

Wir konnten die Tabelle mit dem öffentlichen anon-Schlüssel aus deinem Frontend abfragen und haben Datensätze zurückbekommen. Das heißt: Jeder, der deine Seite öffnet, kann die vollständige Tabelle herunterladen — einschließlich der Zeilen anderer Nutzer.

Fundstelle:
https://xyzcompany.supabase.co/rest/v1/profiles?select=*
Auszug:
HTTP 200 · 1.284 Datensätze · Felder: id, email, full_name, stripe_customer_id

So behebst du es

In der Supabase-Konsole unter Authentication → Policies für die Tabelle `profiles`:

```sql
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Eigenes Profil lesen"
  ON profiles FOR SELECT
  USING (auth.uid() = id);

CREATE POLICY "Eigenes Profil ändern"
  ON profiles FOR UPDATE
  USING (auth.uid() = id);
```

Wichtig: `ENABLE ROW LEVEL SECURITY` allein sperrt alles; ohne Policy kommt auch die eigene App nicht mehr an die Daten. Beides gehört zusammen.

Danach erneut prüfen — dieser Scan ist der Nachweis, dass es gewirkt hat.
hochMitgelieferte Dateien

Source Maps öffentlich erreichbar

Deine Source Maps liegen neben dem Bundle und sind ohne Anmeldung abrufbar. Damit lässt sich dein ungebauter Originalcode rekonstruieren — mit Dateinamen, Kommentaren und der Ordnerstruktur deines Projekts.

Fundstelle:
/assets/index-Bq7fK2mP.js.map
Auszug:
HTTP 200 · 2,1 MB · "sources":["src/lib/auth.ts","src/lib/stripe.ts", …]

So behebst du es

In `vite.config.ts`:

```ts
export default defineConfig({
  build: { sourcemap: false },
});
```

Bei Next.js: `productionBrowserSourceMaps: false` (das ist bereits der Standard — prüfe, ob es irgendwo auf `true` gesetzt wurde).

Danach neu bauen und veröffentlichen. Vorhandene `.map`-Dateien auf dem Server löschen: Ein neuer Build entfernt sie nicht zwangsläufig.
mittelAuslieferung

Keine Content-Security-Policy gesetzt

Ohne Content-Security-Policy kann eingeschleuster Code in deiner Seite beliebige Skripte nachladen. Das ist der Unterschied zwischen einer harmlosen und einer ausgenutzten XSS-Lücke.

Fundstelle:
https://beispiel-app.de/
Auszug:
Antwortheader enthalten weder content-security-policy noch content-security-policy-report-only

So behebst du es

Startpunkt für eine typische SPA:

```
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
```

Rolle sie zuerst als `Content-Security-Policy-Report-Only` aus und sieh in der Browser-Konsole nach, was blockiert würde. Erst wenn nichts Wichtiges mehr auftaucht, auf den scharfen Header umstellen.
geringAuslieferung

Referrer-Policy fehlt

Ohne Referrer-Policy schickt der Browser die vollständige Adresse deiner Seite an fremde Server mit, sobald jemand einen Link nach außen anklickt — samt Parametern.

Fundstelle:
https://beispiel-app.de/
Auszug:
Antwortheader enthalten kein referrer-policy

So behebst du es

Header ergänzen:

```
Referrer-Policy: strict-origin-when-cross-origin
```

Das ist der Wert, den moderne Browser ohnehin als Standard verwenden — ihn ausdrücklich zu setzen macht das Verhalten unabhängig vom Browser des Besuchers.
mittelE-Mail-Zustellung

Kein DMARC-Eintrag

Ohne DMARC kann jeder E-Mails mit deiner Absenderadresse verschicken. Für Phishing gegen deine eigenen Nutzer ist das die halbe Miete — und es trifft ausgerechnet die Leute, die dir vertrauen.

Fundstelle:
_dmarc.beispiel-app.de
Auszug:
NXDOMAIN — kein TXT-Eintrag vorhanden

So behebst du es

Als TXT-Eintrag anlegen, Name `_dmarc`:

```
v=DMARC1; p=none; rua=mailto:dmarc@beispiel-app.de
```

Beginne mit `p=none` — das verwirft noch nichts, sammelt aber Berichte darüber, wer in deinem Namen versendet. Wenn die Berichte sauber aussehen, auf `p=quarantine` und später `p=reject` hochstellen.

Zuerst mit `p=reject` zu starten, kann eigene Mails aus Newslettern oder Buchhaltungssystemen unzustellbar machen.
HinweisErkannter Aufbau

Mit Lovable gebaut, Supabase als Backend

Erkannt an der Bundle-Struktur und den aufgerufenen Adressen. Diese Angabe ist kein Mangel — sie steuert, welche Tiefenprüfungen für deine App überhaupt sinnvoll sind.

Fundstelle:
https://beispiel-app.de/
Auszug:
lovable-tagger im Bundle · xyzcompany.supabase.co als API-Ziel

So behebst du es

Nichts zu tun. Wir nennen es, weil daran hängt, welche Prüfungen wir für dich ausführen — und weil du wissen sollst, was von außen über deinen Aufbau erkennbar ist.

Und wie sieht es bei dir aus?

Der Scan ist kostenlos und dauert etwa zwanzig Sekunden. Du siehst sofort, wie viele Befunde es gibt und wie schwer sie wiegen.

Eigene App kostenlos scannen