~/blog/consent-gate-never-attachedPOSTED
von Shady Nathan Tawfik · 7. Oktober 2026 · 6 min

Das Consent-Gate, das nie angehängt war: Ein plattformweiter Tracking-Bypass

Eine kommunale Drupal-Multisite mit vier Domains zeigte auf Inhaltsseiten ein perfektes Consent-Setup — und auf genau den Seiten, auf denen Einwilligung am wichtigsten ist, gar keines. Das Banner war nicht kaputt: Die Consent-Bibliothek war auf System- und Rechtsrouten nie angehängt, sodass Analytics und ein Meta-Pixel vor jeder Einwilligung liefen.

Interaktiv[blog-2.0]

TL;DR: Auf der Startseite sah das Consent-Setup vorbildlich aus — Tracking-Tags wurden in text/plain-Templates umgeschrieben und warteten auf die Einwilligung. Auf /impressum, /datenschutz, /user/login und einer AJAX-Newsletter-Route derselben Plattform wurden dieselben Tags als ausführbare Skripte gerendert: Analytics und ein Meta-Pixel feuerten ohne Einwilligung, ein Endgeräte-Cookie wurde ohne Secure gesetzt, und es erschien kein Banner. Vier Domains, derselbe Defekt. Die Lehre: Consent-Software ist ein Attachment-Problem — und man testet jede Routenklasse, nicht das Banner.

Die Ausgangslage

Eine kommunale Marketing-Organisation betreibt ihre Stadtmarke auf einer Drupal-Multisite mit vier Domains. Eine Plattform, ein Consent-Manager, ein Analytics-Stack. Ich sollte den Webauftritt von Ende zu Ende prüfen — und begann dort, wo jeder Besucher beginnt: Startseite, Rechtsseiten, Login, Formulare.

Die Startseite war beruhigend. Der Consent-Manager schrieb jedes Tracking-Tag in einen inerten Template-Typ um, Analytics- und Pixel-Bibliotheken luden erst nach der Einwilligung, und ein frisches Browserprofil zeigte null Third-Party-Requests. So soll das aussehen.

Dann richtete ich denselben Test mit frischem Profil auf die Rechtsseiten — auf die Seiten, die ein Besucher genau deshalb öffnet, um zu verstehen, was mit seinen Daten passiert. Dort feuerte das Tracking sofort: kein Banner, keine Einwilligung, trotzdem Speicherzugriff.

Ich habe alle identifizierenden Informationen entfernt. Das Ziel ist nur nach Branche und Technologieklasse beschrieben, damit das Muster wiederverwendbar bleibt.

Das Muster

Der Defekt war kein kaputtes Banner und kein falsch konfigurierter Dienst. Die Consent-Bibliothek, die Tracking-Tags in Opt-in-Templates umschreibt, war auf Inhaltsseiten angehängt — und auf den System- und Rechtsrouten nicht. Dort renderten dieselben Tracking-Module als normale, ausführbare Skripte. Der Besucher wird ausgerechnet auf den Seiten getrackt, auf denen die Website erklärt, dass ohne Einwilligung niemals getrackt würde.

Der Beweis ist eine Routen-Matrix, keine Einzelprüfung

Eine einzelne Prüfung auf der Startseite beweist nichts. Entscheidend war derselbe Probe-Lauf über jede Routenklasse: Inhalte, Rechtsseiten, Login, AJAX-Endpunkte und die Fehlerseite. Das Ergebnis war eine Matrix mit einer grünen Zeile (Inhalte) und vier roten (System und Recht). Ein frisches Browserprofil, Cache-Busting und keine Interaktion sind zwingend — ein warmer Cache oder eine frühere Consent-Entscheidung verdeckt den Defekt.

Die Ursache war im HTML sichtbar

Auf gated Seiten tragen die Tags type="text/plain" und ein data-cookieconsent-Attribut; Konfiguration und Preloader der Consent-Bibliothek stehen im Quelltext. Auf den betroffenen Routen fehlten diese Referenzen vollständig — null Verweise auf die Consent-Bibliothek im HTML, während die Tracking-Skripte als ausführbare <script>-Elemente ausgegeben wurden. Die 404-Seite band die Bibliothek dagegen wieder ein. Damit ist es ein routenabhängiger Attachment-Bug, keine globale Fehlkonfiguration: Das Modulverhalten ist korrekt, der Attachment-Scope ist falsch.

TL;DR: Die Startseite wirkte vorbildlich: Tracking-Tags inert, null Third-Party-Requests vor Opt-in. Auf den Rechts-, Login- und AJAX-Routen desselben Vier-Domain-Bestands renderten dieselben Tags ausführbar — Analytics und ein Meta-Pixel feuerten ohne Einwilligung, _fbp wurde ohne Secure gesetzt, und kein Banner erschien. Das Gate war auf diesen Routen nie angehängt.

Befunde

SchwereBefundBeleg
HOCHConsent-Gate fehlt auf System- und Rechtsrouten aller vier DomainsFrisches Headless-Profil: Analytics + Meta-Pixel laden, _fbp ohne Secure gesetzt, kein Banner; Inhaltsseiten korrekt gated
MITTELZwei Domains der Familie ganz ohne SPF, eine ohne DMARC/DKIMDNS-TXT-Records; gefälschte Mails im Markennamen sind zustellbar
MITTELÖffentlicher Modul-Bauplan (README, 11 KB) auf allen vier DomainsImporter, externer API-Endpunkt, Klartext-Key-Hinweis, nächtliche Cron-Zeiten
MITTELModul-Test-Skript auf allen vier Domains anonym ausführbarHTTP-200-JSON-Endpunkt in Produktion erreichbar
MITTELAnalytics-Server drei Security-Releases hinterherVersion durch öffentliche Changelog-Datei offengelegt; XSS-Escaping-Fixes fehlen
NIEDRIGVersions-Offenlegung, keine security.txt, kein CAA, Installer-Redirect über Klartext-HTTPHeader und DNS

Der Angriffspfad

Consent-Bibliothek auf Inhaltsseiten angehängtSystem- und Rechtsrouten ausgenommenTracking-Tags rendern dort ausführbarAnalytics und Meta-Pixel feuern vor Opt-inEndgeräte-Cookie ohne Secure gesetztDatenfluss an Analytics und MetaRechtliches Risiko und Tracking von Privatsphäre-suchenden Besuchern

Reproduktion im Labor

Jede Probe unten richtet sich gegen eine selbst kontrollierte Lab-Multisite. Nichts davon zielt auf ein Live-System.

~/code/bash bash
# 1. Kontrolle: Gated die Inhaltsseite ihre Tags und hängt sie die Bibliothek an?
curl -s http://lab.local/ | grep -o 'type="text/plain"[^>]*' | head -3
curl -s http://lab.local/ | grep -c 'consent-preloader'
# <- inerte Template-Tags, Preloader vorhanden

# 2. Dieselbe Prüfung auf einer Systemroute
curl -s http://lab.local/user/login | grep -c 'consent-preloader'
curl -s http://lab.local/user/login | grep -c 'var _paq'
# <- 0 Bibliotheks-Referenzen, ausführbarer Analytics-Schnipsel

# 3. Der eigentliche Test: frisches Profil, keine Interaktion, pro Routenklasse
for u in / /impressum /datenschutz /user/login /ajax/newsletter; do
  TARGET="http://lab.local$u" node consent-audit.js
done
# <- frisches Profil auf den Rechtsrouten: Third-Party-Requests + Cookie, kein Banner
~/code/text text
# consent-audit.js prüft, pro Route:
#   Third-Party-Requests vor Consent == 0
#   Cookies vor Consent              == 0
#   Banner sichtbar, sobald Tracking existiert == true
# jede Route, die die ersten beiden Zusicherungen verletzt, ist ein Befund.

Erkennung im eigenen Bestand

  • Teste Routenklassen, nicht Seiten: Inhalte, Rechtsseiten, Login, AJAX-Endpunkte, Suche, Fehlerseite, Druckansichten. Consent-Bibliotheken hängen pro Route an; ein ausgenommenes Template reicht.
  • Nutze für jede Probe ein frisches Browserprofil mit deaktiviertem Cache. Eine frühere Consent-Entscheidung oder ein warmer Seiten-Cache zeigt grün, wo der Besucher rot sieht.
  • Prüfe das HTML-Differential: Gated Tags tragen type="text/plain" plus Consent-Attribut, und die Bibliotheks-Konfiguration steht im Quelltext. Stehen Tracking-Tags auf einer Route in ausführbaren <script>-Elementen, fehlt dort das Gate — unabhängig davon, was das Banner behauptet.
  • Prüfe das Ergebnis, nicht das Tooling: null Third-Party-Requests und null Cookies vor Opt-in. Mach daraus einen CI-Check über eine Routenliste und alarmiere bei Regressionen.
  • Halte die Datenschutzerklärung konsistent mit der Realität. Ein Pixel, der als „berechtigtes Interesse" beschrieben ist, während die Consent-Konfiguration ihn mit needConsent führt, ist ein Widerspruch, den ein Prüfer findet.

Behebung

~/code/text text
# sofort
1. Consent-Bibliothek global anhängen (Drupal: hook_page_attachments),
   nicht über Blöcke pro Route; die Block-Sichtbarkeit korrigieren, die
   System- und Rechtsrouten ausschließt
2. AJAX-Newsletter-Route entfernen oder gaten; alle Caches leeren
3. Headless gegenprüfen, pro Routenklasse: 0 Third-Party-Requests vor Consent
4. tests/, docs/ und README* unter /modules/ blocken; Klartext-Key rotieren

# innerhalb einer Woche
5. Analytics-Server über die fehlenden Security-Releases aktualisieren
6. E-Mail-Policy vereinheitlichen: SPF -all, DKIM und DMARC auf jeder Domain
7. Header-Baseline auf jedem Vhost: HSTS, CSP, X-Frame-Options,
   Referrer-Policy, Permissions-Policy

# innerhalb eines Monats
8. Regressionstest in CI und in die Rollout-Checkliste jeder
   Consent-Tool- oder Template-Änderung aufnehmen

Sobald ein Angreifer Zugriff hat, kann er folgende Aktionen durchführen:

Besucher auf Rechts- und Login-Seiten ohne Einwilligung tracken — Endgeräte-Speicherzugriff vor Opt-in (TTDSG §25)
Zwei Marken spoofbar (gar kein SPF): gefälschte Gewinnspiel- und Ticket-Mails an Kunden
Öffentlicher Modul-Bauplan: Importer-Endpunkte, Cron-Fenster, Klartext-Key-Hinweis
Analytics-Server drei Security-Releases hinterher — XSS-Escaping-Fixes fehlen
Test-Skript in Produktion auf allen vier Domains anonym ausführbar

Fazit

  • Ein Consent-Banner ist kein Consent-Gate. Entscheidend ist, ob die Tracking-Tags auf jeder Route inert sind — und das ist eine Attachment-Frage, keine UI-Frage.
  • Die Seiten, die Nutzer zum Thema Tracking aufsuchen, sind der schlechteste Ort für einen Bypass. Teste Rechtsseiten zuerst, nicht zuletzt.
  • Eine grüne Startseiten-Zeile bedeutet nichts. Nur eine Routen-Matrix mit frischen Profilen ist ein ehrlicher Test.
  • Derselbe Bestand hat selten genau einen Rest. Ein Routen-Scope-Bug sitzt neben öffentlicher Modul-Dokumentation, einem offenen Test-Endpunkt und einer gespaltenen E-Mail-Policy.
  • Fix das Attachment einmal und verifiziere das Ergebnis pro Route in CI — sonst öffnet die nächste Template-Änderung das Gate still wieder.
Shady Nathan Tawfik

Gründer & Cyber IT Security Engineer in Bielefeld. Offensive Security, Audits und Fullstack-Entwicklung. Mehr auf

Nur zu Bildungszwecken. Alle reproduzierbaren Befehle zielen auf meine eigene Lab-Umgebung (localhost), nie auf ein laufendes System. © 2026