TL;DR: Die Consent-Plattform war installiert, lizenziert und aktuell. Der Banner rendert. Google Consent Mode war aktiv. Und trotzdem verließ ein frisches Browser-Profil den ersten Seitenaufruf mit
_ga,_gcl_au,_fbpundnmstatim Jar — nach Kontakt mit acht Dritt-Anbietern, von denen keiner einen Klick verlangte. Die Plattform lief im Beobachtungsmodus, nicht im Erzwingungsmodus: Consent Mode signalisiert eine Entscheidung, er verhindert nicht das Laden des Tags. Die Abhilfe wurde im Lab-Spiegel desselben Stacks bewiesen: vier Pre-Consent-Feuerungen wurden null.
Die Ausgangslage
Eine mittelgroße Digitalagentur — genau die Art Unternehmen, deren eigene Website als Referenz für die Kunden gelten soll — bat um einen externen Blick auf ihre öffentliche Web-Oberfläche. Kein Penetrationstest, kein Eindringen: eine Black-Box-Prüfung dessen, was ein normaler Besucher (und ein normaler Crawler, und ein normaler Wettbewerber) ohne Anmeldung sehen kann.
Das Perimeter entpuppte sich als langweilig im guten Sinne. Der Reverse-Proxy blockte Dotfiles und Management-Pfade, kein Actuator, kein Jenkins, kein Solr, keine Debug-Konsole, das Zertifikat deckte die komplette Marken-Familie ab, und die Seite war eine Individualentwicklung statt eines Plugin-CMS. Wer das gebaut hat, hat mitgedacht.
Dann startete der Browser-Test, und die Geschichte kippte.
Ich habe alle identifizierenden Informationen entfernt. Das Ziel ist nur über Branche und Technologieklasse beschrieben, alle Tag-IDs sind unkenntlich gemacht, damit das Muster wiederverwendbar bleibt, ohne jemanden zu exponieren.
Das Muster
Ein Consent-Banner ist ein UI-Element; Blockieren ist eine eigene Funktion
Die Verwechslung ist verständlich. Eine Consent-Plattform tut zwei grundverschiedene Dinge: Sie erhebt eine Entscheidung und sie erzwingt sie. Banner, Einstellungsdialog, Rechtstexte — das ist die Erhebungshälfte. Die Erzwingungshälfte ist eine Konfiguration: Welcher Dienst darf in welchem Zustand laden, und was passiert mit einem Tag, der noch nicht erlaubt ist.
Hier war die Erzwingungshälfte nie konfiguriert. Jeder Dienst lief effektiv im „Beobachten"-Modus — sichtbar in den Dashboards, gemeldet in den Reports, und trotzdem geladen. Der Banner sah perfekt aus, weil der Banner perfekt war. Er beantwortete eine Frage, auf die niemand reagierte.
Consent Mode signalisiert; er blockiert nicht
Google Consent Mode verdient einen eigenen Absatz, weil er die häufigste Quelle dieses falschen Sicherheitsgefühls ist. Consent Mode übergibt einen Zustand an Googles Tags: „dieser Nutzer hat Analytics abgelehnt", „dieser Nutzer hat Ads abgelehnt". Was Google mit diesem Signal tut, ist Googles Sache — es beeinflusst, wie Daten verwendet werden, nicht ob der Tag läuft. Das Skript lädt, das Cookie wird geschrieben, die Anfrage verlässt den Browser des Besuchers.
Wer Blockieren will, muss dafür sorgen, dass der Tag bis zur Erlaubnis nicht ausgeführt wird. Das ist eine Loader-Entscheidung, keine Signal-Entscheidung.
Der Beleg ist nicht „der Banner sieht gut aus" — es ist ein frisches Profil
Der einzige Test, der etwas beweist, ist ein frisches Browser-Profil, ohne Cache, ohne früheren Consent-Zustand, ohne jede Interaktion, das Netzwerk und Cookie-Jar beim ersten Seitenaufruf beobachtet. Warme Profile und bereits erteilte Einwilligungen verstecken den Defekt vollständig. In unserem Lauf:
- acht Dritt-Anbieter-Hosts wurden vor jeder Interaktion kontaktiert
- fünf Tracking-Cookies plus das Session-Cookie der Anwendung wurden gesetzt
- kein First-Party-Cookie trug
Secure— auf einer HTTPS-only-Seite - das Session-Cookie war
HttpOnly, aber nichtSecure
Der Rest des Perimeters erzählte seine eigene Geschichte
Während der Browser offen war, sammelte die Prüfung außerdem: keine Content-Security-Policy, kein X-Content-Type-Options, keine Permissions-Policy, HSTS ohne includeSubDomains, SPF endend auf ~all und DMARC auf p=quarantine — dazu öffentliche DNS-Verifikations-Records, die den kompletten SaaS-Stack der Agentur enumerierten (zwei Google-Dienste, JetBrains, Miro und ein KI-Anbieter) für jeden, der nachsehen wollte.
Befunde
| Schwere | Befund | Beleg |
|---|---|---|
| HOCH | Tracking vor Einwilligung: Tag-Manager, Analytics, Ads, Meta-Pixel, LinkedIn Ads, eine Analytics-Suite und ein Video-Embed luden beim ersten Aufbau | Netzwerk-Capture mit frischem Profil |
| HOCH | Cookies ohne Einwilligung geschrieben: _ga, _ga_*, _gcl_au, _fbp, nmstat plus Video- und LinkedIn-Cookies | Cookie-Dump mit Flags |
| MITTEL | Kein Secure-Flag auf irgendeinem First-Party-Cookie, inklusive der Anwendungs-Session | Cookie-Flags |
| MITTEL | Fehlende CSP, nosniff, Permissions-Policy, COOP/CORP; HSTS ohne includeSubDomains/preload; veraltetes X-XSS-Protection | Response-Header |
| MITTEL | SPF-Softfail, DMARC nur Quarantine | öffentliches DNS |
| NIEDRIG | robots.txt, sitemap.xml, security.txt fehlen | Pfad-Tests |
| NIEDRIG | SaaS-Stack über öffentliche Verifikations-TXT-Records enumerierbar | öffentliches DNS |
| INFO | Consent-Plattform vorhanden und rendert — Erzwingung nicht konfiguriert | Shadow-DOM-Inspektion |
Der Angriffspfad
- Erst das Profil. Abgesehen von der Consent-Erzwingung liefern die öffentlichen DNS-Records dem Angreifer den Tool-Stack. Danach lautet die Frage nicht „wie komme ich rein", sondern „welcher dieser fünf Anbieter ist das schwächste Glied".
- Die Marke fälschen. Mit SPF auf Softfail und DMARC auf Quarantine überstehen gefälschte Rechnungs- oder Bewerbungsmails im Namen der Agentur die meisten Filter — und die Postfächer einer Agentur sind voll mit Kundendokumenten.
- Auf die Session warten. Das Session-Cookie reist ohne
Secure. Eine einzige Klartext-Anfrage irgendwo auf dem Pfad — ein vertippteshttp://, ein Captive Portal, ein altes Lesezeichen — genügt, um es abzugreifen. - Den Browser vorbereiten. Keine CSP und kein
nosniffist für sich genommen kein Exploit; es ist das Fehlen des Sicherheitsnetzes, das aus einem injizierten String eine Ausführung macht. - Dann leise das Tracking. Acht Dritt-Anbieter-Hosts erhalten Besucherkennungen — inklusive Bewerbern auf den Karriereseiten — vor der Einwilligung. Nach TTDSG § 25 und DSGVO Art. 6 ist das keine Formalie; es ist der Befund, mit dem eine Aufsichtsbehörde anfängt.
Reproduzieren — und den Fix beweisen
Befunde, die sich nicht reproduzieren lassen, sind Meinungen. Also wurde derselbe Stack als Lab-Spiegel nachgebaut: eine Mock-Anwendung hinter einem Reverse-Proxy, ein Consent-Gate mit Tag-Loader und ein serverseitiger Zähler, der festhält, welcher Tag in welchem Consent-Zustand gefeuert hat.
| Szenario | Gemessenes Ergebnis |
|---|---|
| Ungehärteter Build, keine Interaktion | 4 Tag-Feuerungen vor Einwilligung (Analytics, Ads, Meta, LinkedIn) |
| Gehärteter Build, keine Interaktion | 0 Feuerungen |
| Gehärteter Build, nach Opt-in | 0 vor Einwilligung / 4 nach Einwilligung |
| Session-Cookie | HttpOnly → HttpOnly; Secure; SameSite=Lax |
| Härtende Header | 0 → CSP + nosniff (+ Permissions-Policy, HSTS preload) |
Das ist der Unterschied zwischen „wir empfehlen Blockieren" und „Blockieren erzeugt genau diesen Zustand, hier ist der Zähler".
So erkennen Sie es im eigenen Bestand
- Frisch-Profil-Test bei jedem Release, idealerweise in der CI: Seite mit sauberem Profil laden und den Build fehlschlagen lassen, wenn vor der Einwilligung ein Dritt-Anbieter-Host kontaktiert wird.
- Consent-Plattform: auf Dienste reporten, die konfiguriert sind, aber nie blockieren. Ein Dienst, der nur in der Beobachten-Spalte auftaucht, ist der Defekt.
- Cookie-Audit:
Secureauf allen First-Party-Cookies erzwingen und jedes Tracking-Cookie vor Opt-in als Release-Blocker behandeln. - Header-Basislinie: CSP,
nosniff,Permissions-Policy, HSTS mitincludeSubDomains— als Pipeline-Gate prüfen, nicht als PDF. - DNS-Review quartalsweise: SPF/DMARC-Posture und die wachsende Liste der Vendor-Verifikations-Records.
So beheben Sie es (in dieser Reihenfolge)
- P0 — Erzwingen statt beobachten. In der Consent-Plattform jeden nicht-essenziellen Dienst auf Blocking stellen und den Tag-Manager nur über den kontrollierten Modus laden. Mit frischem Profil verifizieren: null Dritt-Anbieter-Requests vor Opt-in.
- P0 — Datenschutzerklärung an die tatsächlichen Datenflüsse anpassen, inklusive Übermittlungsgrundlage für US-Dienste.
- P1 — Cookies.
Secureauf allen First-Party- und Session-Cookies;SameSiteprüfen. - P1 — Header. CSP (Start report-only),
nosniff,Permissions-Policy, COOP/CORP, HSTS aufincludeSubDomains; preload. - P1 — E-Mail. SPF auf
-all, DMARC aufp=reject, sobald die Reports sauber bleiben. - P2 — Hygiene.
robots.txt,sitemap.xml,security.txt; ungenutzte Verifikations-Records entfernen; Video-Embeds aufyoutube-nocookieoder Click-to-Load umstellen.
Once an attacker gains access, they can perform the following actions:
Fazit
Eine Consent-Plattform ist kein Compliance-Schalter. Sie ist ein Loader — und ein Loader blockiert nur das, was man ihm sagt. Der Banner rendert weiterhin wunderschön, während jeder Tag, den man zu konfigurieren vergessen hat, daran vorbeifährt. Der einzige ehrliche Test ist ein frisches Profil ohne Interaktion, und der einzige ehrliche Fix ist einer, dessen Ergebnis man zählen kann.