Felix Riesterer: Wir erzwingen Ihre Einstimmung!

In der Netzgemeinde hat sich der Begriff des Cookie-Terror-Banners längst etabliert. Hintergrund ist eine EU-Vorgabe, dass Seitenbetreiber nur dann Cookies auf dem Gerät ihrer Besucher speichern dürfen, wenn diese dem zustimmen.

Das hat dazu geführt, dass man seit Jahren auf sehr vielen Webseiten Einblendungen vorfindet, die sich über den eigentlichen Seiteninhalt ausbreiten und sehr aufdringlich nach der Zustimmung verlangen, dass die Seite Cookies speichern darf. Solche Einblendungen sind im Alltag störend und nicht selten absichtlich unbequem in der Bedienung, wenn man nicht blind einfach alles abnicken möchte.

Ansicht der Seite heise.de mit offenem Cookie-Banner

Entweder man schont seine Nerven und willigt brav in alles ein, was dem Ausspähen von Daten Tür und Tor öffnen kann, oder man installiert sich ein passendes Browser-Plugin, das einem die Werbung und datenschnüffelnde Cookies vom Hals hält wie z.B. uBlock origin. Wir wären aber nicht SELFHTML, wenn wir nicht auch eine Idee hätten, wie man sich nervige Einblendungen vom Hals halten könnte.

Solche Cookie-Banner werden per JavaScript über den eigentlichen Seiteninhalt gelegt, indem sie das Dokument im Browser um gewisse Elemente erweitern. Könnte man jetzt sein eigenes JavaScript-Programm ausführen, wäre es denkbar, diese Elemente wieder aus dem Dokument zu entfernen. Aber wie soll man ein JavaScript in eine fremde Seite einbinden, wenn man keinen Schreibzugriff auf dem jeweiligen Webserver hat?

Userscripte im Browser via Plugin

Mit entsprechenden Browser-Plugins wie z.B. Tampermonkey kann man eigene JavaScript-Dateien im Kontext einer fremden Website ausführen lassen. Damit kann man sich ein Script schreiben, das so manches Cookie-Banner erkennt und entfernt.

JavaScript im Browser bietet mit dem MutationObserver ein geeignetes Werkzeug an, um zu erkennen, wenn Teile des Dokuments im Browser verändert wurden, weil z.B. ein Element per JavaScript hinzugefügt wurde. Damit ist es dann ein Leichtes, auf bestimmte Elemente, Klassennamen oder Attributwerte zu prüfen, um die einschlägigen Banner zu finden. Das folgende Script bietet zwar nicht den Komfort und die Sicherheit, die ein Browser-Plugin wie uBlock origin bietet, aber als Spielerei gegen Cookie-Terror-Banner ist es allemal ein netter Zeitvertreib, vor allem dann, wenn man die jeweiligen Erkennungsmerkmale im Seiteninspektor herausfindet, um sie dann im Script zu ergänzen.

Das folgende Code-Listing kann als lokale Script-Datei in Tampermonkey hinterlegt werden. Die einzeiligen Kommentare am Anfang steuern auf welchen Seiten im Internet es eingebunden werden soll (aktuell auf allen, siehe die @match-Regeln). Hinweise zu seiner Funktionalität stehen nach dem Code-Listing.

// ==UserScript==
// @name Anti Terror Banner Script
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author Anti Terrorist Banner Coder
// @match https://*/*
// @match http://*/*
// @icon none
// @grant none
// @run-at document-end
// ==/UserScript==
 
(function () {
  'use strict';
   
  const terrorBanners = [
    // sp_message_container
    {
      elements: '[id^="sp_message_container"]',
      classes: { element: "html", name: "sp-message-open" }
    },
    // onetrust
    { elements: "#onetrust-consent-sdk" },
    // ion-modal
    { elements: "ion-modal" },
    // cc_banner
    { elements: ".cc-banner" },
    // usercentrics
    { elements: "#usercentrics-root" },
    // didomi
    {
      elements: "#didomi",
      classes: { element: "body", name: "didomi-popup-open" }
    },
    // cmpbox
    {
      elements: "#cmpbox, #cmpbox2",
      attributes: { element: "body", name: "style" }
    },
    // cmp-modal
    {
      classes: [
        { element: "*", name: "modal-backdrop" },
        { element: "*", name: "modal-cmp" }
      ]
    },
    // needsclick
    { elements: "div.needsclick" },
    // snigel
    { elements: "div.snigel-cmp-framework" },
    // gdpr-consent-tool
    { elements: "div#gdpr-consent-tool-wrapper" }
  ];
   
  const observer = new MutationObserver(mutations => {
   
    terrorBanners.forEach(banner => {
     
      if (banner.elements) {
        Array.from(document.querySelectorAll(banner.elements)).forEach(
          element => element.parentNode.removeChild(element)
        );
      }
       
      if (banner.attributes) {
        const attributes = (
          banner.attributes instanceof Array
          ? banner.attributes
          : [banner.attributes]
        );

        attributes.forEach(data => {
          if (data.element && data.name) {
            Array.from(document.querySelectorAll(data.element)).forEach(
              element => element.removeAttribute(data.name)
            );
          }
        });
      }

      if (banner.classes) {
        const classes = (
          banner.classes instanceof Array
          ? banner.classes
          : [banner.classes]
        );

        classes.forEach(data => {
          if (data.element && data.name) {
            Array.from(document.querySelectorAll(data.element)).forEach(
              element => element.classList.remove(data.name)
            );
          }
        });
      }
    });
  });

  observer.observe(document.body, {
    subtree: true,
    childList: true,
    attributes: false,
    characterData: false,
    attributeOldValue: false,
    characterDataOldValue: false
  });

})();

Im großen Array terrorBanners stehen einzelne Objekte, in denen die jeweiligen Erkennungsmerkmale hinterlegt sind. Ein solches Objekt kann diese Eigenschaften haben:

  • elements - Selektor für Elemente, die zu entfernen sind
  • attributes - Objekt (oder ein Array solcher Objekte), welches Namen von Attributen definiert, die von Objekten entfernt werden müssen:
    • element - Selektor für Elemente, die dieses Attribut haben können
    • name - Name des Attributs
  • classes - Objekt (oder ein Array solcher Objekte), welches Namen von Klassen definiert, die von Objekten entfernt werden müssen:
    • element - Selektor für Elemente, die diese Klasse haben können
    • name - Name der Klasse

Fazit

Ein solches Script kann die Bedienung von Seiten erleichtern, weil es die Einblendungen wieder entfernt, welche die Benutzung der Seite ansonsten blockieren. Es gibt aber Banner-Mechanismen, die den eigentlichen Seiteninhalt durch ein unscharfes Hintergrundbild ersetzen. Auf solchen Seiten sieht man dann natürlich keine brauchbaren Inhalte, wenn man das Cookie-Banner entfernt. Und es ist keinesfalls garantiert, dass eine Seite nicht schon vor der Einwilligung durch den Benutzer mindestens ein Cookie setzt, auch wenn das klar gegen die EU-Verordnung verstößt. Aber für den Hobby-Bastler kann es Vergnügen bereiten, sich auf diese Weise gegen allzu penetrante Gängelungen zu wehren.

  1. Nur eine Anmerkung, hauptsächlich für die „ist ja nicht so schlimm“ Fraktion gedacht:

    Bereits vor ettlichen Monaten, als die geschilderten Banner langsam merkbar auftragen, bin ich über die Seite eines Baumarktes gestolpert. Eigentlich, würde man denken, soll die Kunden in die Läden locken. Den potentiellen Kunden also etwas anbeidern.

    Aber da war er nun, dieser „Halb-Bildschirm“ mit 𝍌🛃 davor. Netterweise gabe es sogar „Detailinformationen“ zu den (behaupteten?) Optionen: funktionale Cookies usw.

    Das „Interessante“ daran war, daß die Seite mit JS (oh, die hat damals durchaus noch, wenn auch mit etwas Mühe, ohne funktioniert; ganz ohne Cookie-Banner und mit „Keine Cookies speichern“!) zwingend[1] vorausgetzt hat, daß u. A. nicht nur Google (die kriegen sowieso alles mit, was irgend einen Google-[Geheim-]Dienst[2] nutzt) sondern auch diverse Asoiale Medien und noch ein paar weniger bekannte Datensammler unbedingt auch „herumkeksen“ durften.

    Den Bundesdatenschutz-Fritzen hat es wohl nicht interessiert, hab’ dazu jedenfalls nie eine Antwort bekommen. Und: wer sagt denen jetzt, daß sie damit auf alle Fälle genau deswegen auf mindestens einen Kunden „auf immer und ewig“ verzichten müssen? Etwa jene, die so und so keine Cookies platzieren konnten?


    1. also bei der „datensparsamsten“ Einstellungsmöglichkeit! ↩︎

    2. wenn man Scripte vom „Server A“ bezieht (welche dann auch noch weiteren Kram, auch weitere Scripte, nachladen können), dann kann so ein eingebettetes Skript nie und nimmer mit „A“ telefonieren? Und z. B. dieses “big data” von Analytics läuft auf dem kleinen, als intelligentes Terminal (immerhin: nur mit JS, aber ohne Java) Computer? Tja, da liefert jemand ab. Nicht zu knapp. Die Ware “user” an die Kraken. ↩︎

    1. Die Empörung kann ich gut nachvollziehen. Leider kann ich dem Text ab dem Absatz 'Das „Interessante“ daran war, ...' nicht mehr so richtig folgen.

      Für mich wäre eine Kurzfassung / Übersicht oder so an der Stelle hilfreicher: Was war so schlimm an der Stelle?

      1. Hallo micha,

        es wurden Kekse als zwingend notwendig behauptet, und nix sah die Notwendigkeit anders. Dabei sind Google- oder Facebook-Kekse für die meisten Seiten zwingend, weil sie ohne Datenverkauf keine Einnahmen haben.

        Dagegen hilft auch Felix' Tool nicht. Wer Daten sammeln und verkaufen will, tut es. Dagegen hilft nur der Inkognito-Modus (aber wer weiß, was die Dunkle Seite der Macht im Inkognitomodus trotzdem alles verpetzt) oder ein Browser, der nicht von einem Nichtdatensammler verbreitet wird. Leider sind diese Browser in ihrer Funktionalität nicht ganz auf der Höhe. Weil weniger Geld da ist, um sie zu pflegen.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Lieber Rolf,

          Dagegen hilft auch Felix' Tool nicht. Wer Daten sammeln und verkaufen will, tut es.

          das ist richtig. Das Tool will nur die Banner automatisch entfernen helfen. Gegen die Datensammelei sind entsprechende Browser-Plugins wie uBlock origin, Privacy Badger und dergleichen sinnvoll.

          Liebe Grüße

          Felix Riesterer

        2. Rrrrrrichtig! Und dazu dann noch: daß jene, die (sowieso) genug Daten dazu gesammelt haben, Browser auch ohne Cookies mit sehr hoher Wahrscheinlichkeit identifizieren können, ist mittlerweile auch schon alt, „in Internet-Zeit gemessen“ sogar sehr alt.

          Z. B. das Timing beim Nachladen gibt Hinweise auf den Inhalt von Caches, vorgehaltene Schriften (vor Ort oder nachgeladen), liefern auch ein Datenhäufchen. Dazu das generelle Verhalten des Browsers … fürs Fingerprinting gibt es ettliche Möglichkeiten. Und die offiziellen Infos, die ein Browser abliefert, können zwar betrachtet, aber auch ignoriert werden. Man suche einfach mal nach z. B. "site:heise.de browser fingerprint" oder … na, das weiß ja sogar Wikipedia.

          Ach ja, noch eine Geschichte: als das damals aufkam, gab es auch schnell Testseiten. Und „Testseiten“. Eine der letzteren hat mir „bescheinigt“, daß meine Installation um so schwerer erkennbar gewesen wäre, je irrwitziger der Useragent-String aussah …

          Und dazu dann noch die „Entdeckung“, daß https wunderbar geeignet ist, um diese angebliche Firewalls (stand so auf den Verpackungen, etwas später wurde daraus meist eine „Firewall-Funktionalität“; also: SPI) der diversen Router ignorieren zu können …

          1. Hallo nix,

            gut, diese Diskussion schließen wir damit jetzt ab.

            Rolf

            --
            sumpsi - posui - obstruxi