Umsetzung der DSGVO

DSGVO, Teil 3

Wie angekündigt, hier ein dritter Teil der Serie zur DSGVO. Die anderen beiden gibt es hier (Teil 1) und hier (Teil 2). Folgende Modifikationen und Einstellungen habe ich vorgenommen:

1. WordPress-Funktionen

Ich empfehle ein eigenes (Child-) Theme, damit alle Änderungen update-sicher sind und nicht bei jedem Theme-Update übergebügelt werden. Grundsätzlich können alle folgenden Änderungen direkt in die functions.php (liegt im Ordner [WordPress-Verzeichnis]/wp-content/themes/[aktivesTheme]/) eingefügt werden:

1.1 Checkbox ins Kommentare-Formular einbasteln

Ich gehe von einem mehr oder weniger standardmäßigem Kommentar-Formular (z.B. via <?php comment_form()?> innerhalb der Datei comments.php) aus. Dann kann man recht einfach eine Funktion schreiben, die via echo html-Elemente in das Formular einfügt. Die Funktion wird via add_action (Doku) an der Stelle comment_form_after_fields eingehakt (s. Hooks). Um die Funktion auch aufzurufen, wenn der/die Benutzende eingeloggt ist, kann comment_form_logged_in_after genutzt werden:

PHP / functions.php

// Checkbox für DS-Einwilligung ins Kommentarformular einfügen
function mm_privacyconsent_field() {
  echo
    '<p class="privacyconsentheadline">Zustimmung zur Datenverarbeitung</p>
     <input id="privacyconsent" name="privacyconsent" type="checkbox" required="required" />'.
    '<label for="privacyconsent">' . __( 'Ich stimme der Verarbeitung der eingegebenen Daten im Sinne der <a target="_blank" href="/datenschutzerklaerung">Datenschutzerkl&auml;rung</a> zu.*' ) . '</label>';
}
// für eingeloggte Benutzende
add_action( 'comment_form_logged_in_after', 'mm_privacyconsent_field' );
// für nicht-eingeloggte Benutzende
add_action( 'comment_form_after_fields', 'mm_privacyconsent_field' );

Das injizierte HTML besteht aus einem Text (<p>), der Checkbox (<input>) und der Beschriftung (<label>). Klassen und IDs für optionale CSS-Styles nicht vergessen! Die IDs des <input>-Objektes ist darüber hinaus für die Zuordnung des <label> notwendig.

Ergebnis:

Checkbox am Ende des Kommentarfeldes

Über das required="required" ist das Feld automatisch ein Pflichtfeld. Um es "noch ein wenig verpflichtender" zu machen bzw. die Kommentierenden mit etwas mehr Nachdruck auf die Datenschutzerklärung aufmerksam zu machen, könnte man mittels jquery den Aktiv-/Inaktiv-Status des "Abschicken"-Buttons an diese Checkbox koppeln.

Dafür wird dem Button (hier: #comments input#submit) standarmäßig die Eigenschaft (.prop(), Doku) disabled und auch (via .addClass(), Doku) eine Klasse mit gleichem Namen gesetzt (für’s CSS, s.u.).

Dann wird an die Checkbox (hier: input#privacyconsent) mittels Eventhandler (.change(), Doku) eine Überprüfung (if($(this).is(":checked"))) angebastelt, die sowohl die Eigenschaft als auch die Klasse disabled je nach Check-Status der Checkbox "umschaltet":

jQuery

// DSGVO Checkbox bei Kommentaren
$(document).ready(function(){
  $('#comments input#submit').prop("disabled", true);
  $('#comments input#submit').addClass( 'disabled' );
  $('input#privacyconsent').change(function(){
    if($(this).is(":checked")) {
      $('#comments input#submit').prop("disabled", false);
      $('#comments input#submit').removeClass( 'disabled' );
    } else {
      $('#comments input#submit').prop("disabled", true);
      $('#comments input#submit').addClass( 'disabled' );
    }
  });
});

Der Klasse disabled kann man dann einfach via CSS ein paar Styles (hier: Deckkraft und Cursor-Form) mitgeben:

CSS

#comments #submit.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

Hier das Ergebnis:

Button-Status hängt am Checkbox-Status, CSS regelt Deckkraft und Cursor-Zeigersymbol.

Find ich gut. 🙂 – bekommt einen Haken

1.2 IP von Kommentierenden nicht speichern …

Die nächste Baustelle bei den Kommentaren ist die Speicherung von IP-Adressen. Diese kann man ebenfalls mit einer Funktion in der functions.php ändern, indem man an der Stelle pre_comment_user_ip (Doku) die IP (Parameter $comment_author_ip) mit "nichts" überschreibt:

php / functions.php

// Keine IP-Adressen von Kommentierenden speichern 
function mm_remove_comment_author_ip( $comment_author_ip ) {
  return '';
}
add_filter( 'pre_comment_user_ip', 'mm_remove_comment_author_ip' );

Quellen u.a.: wp-ninjas.de | blogmojo.de

Ergebnis:

Kommentare mit (unten) und ohne (oben) IP im Redaktionsbereich …
… und in der Datenbank.

1.3 … oder zeitverzögert löschen

Wer nicht im Code herumpfuschen möchte, kann das Plugin Remove Comments IPs nutzen. Dort wird es auch im nächsten Release eine Funktion geben, um die Speicherdauer abweichend zur Voreinstellung (bisher: 60 Tage) einzustellen. Das ist für das Thema IP-Adresse zur Spam-Filterung nutzen recht wichtig. Die Version des Plugins von hier beinhaltet bereits den Filter remove_comment_ip_days_to_deletion, ist aber noch kein offizielles Release.

Da ich die IP-Adresse für den Spamfilter (noch) nicht benötige, speichere ich auch keine IP-Adressen. Datenvermeidung und so 🙂

1.4 Bisherige IP-Adressen von Kommentaren entfernen

Die eventuell in der Datenbank vorhandenen IP-Adressen müssen entfernt werden. Dafür ist leider ein kleiner Datenbank-Eingriff notwendig. Mit dem SQL-Befehl

SQL

UPDATE wp_comments SET comment_author_IP = ' ';

kann man recht einfach alle IP-Adressen in der Datenbank löschen. Anleitungen u.a. auf wp-ninjas.de oder tantedine.de. Da ich mich entschlossen habe, alle "alten" Kommentare zu löschen, habe ich das allerdings gar nicht angewendet.

Das Thema IP-Adressen:

1.5 User Agent nicht speichern

Nach dem gleichen Strickmuster wie das Überschreiben der IP-Adresse (s.o.) funktioniert das "nicht speichern" des User Agent. Lediglich die Stelle, an der der Hook einhakt (pre_comment_user_agent, Doku) und der betroffene Parameter ($comment_agent) sind andere:

php / functions.php

// Keinen User Agent von Kommentierenden speichern
function mm_remove_comment_agent_string( $comment_agent ) { 
  return '';
} 
add_filter( 'pre_comment_user_agent', 'mm_remove_comment_agent_string' );

Ergebnis:

Kommentar mit (oben) und ohne (unten) User-Agent in der Datenbank

Also auch hier mache ich erst mal einen Haken dran:

1.6 Gravatare abschalten

Das ist einfach: Im Redaktionsbereich von WordPress gibt es unter > Einstellungen > Diskussion die Option "Avatare anzeigen". Häkchen entfernen, speichern, fertig:

Easy.

1.7 Emojis abschalten

Hier müssen ebenfalls Funktionen in die functions.php eingefügt werden:

php / functions.php

// Emojis deakivatieren
function mm_disable_emojis() {
  remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
  remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
  remove_action( 'wp_print_styles', 'print_emoji_styles' );
  remove_action( 'admin_print_styles', 'print_emoji_styles' ); 
  remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
  remove_filter( 'comment_text_rss', 'wp_staticize_emoji' ); 
  remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
  add_filter( 'tiny_mce_plugins', 'mm_disable_emojis_tinymce' );
  add_filter( 'wp_resource_hints', 'mm_disable_emojis_remove_dns_prefetch', 10, 2 );
}
add_action( 'init', 'mm_disable_emojis' );

// Emoji-Plugin in TinyMCE deaktivieren
function mm_disable_emojis_tinymce( $plugins ) {
  if ( is_array( $plugins ) ) {
    return array_diff( $plugins, array( 'wpemoji' ) );
  } else {
    return array();
  }
}

//Remove emoji CDN hostname from DNS prefetching hints.
function mm_disable_emojis_remove_dns_prefetch( $urls, $relation_type ) {
  if ( 'dns-prefetch' == $relation_type ) {
    /** This filter is documented in wp-includes/formatting.php */
    $emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2/svg/' );
    $urls = array_diff( $urls, array( $emoji_svg_url ) );
  }
  return $urls;
}

Quelle: kinsta.com

Ergebnis:

Die Wirksamkeit kann ich mit meinen beschränkten Mitteln nicht vollumfänglich testen. Allerdings wird das hier gezeigte Skript nicht mehr geladen, …

Mit der o.g. Funktion wird dieses Skript nicht mehr geladen und dadurch auch keine Verbindung mit dem CDN hergestellt.

… das Skript und die Styles aus dem Header verschwinden, …

Das hier gezeigte Skript und der Style im Header verschwinden auch.

… und auf verschiedenen Geräten werden nun verschiedene (system-eigene?) Emojis angezeigt:

Links: Emojis vom CDN, rechts: Eigene (?) Emojis; beide Screenshots zeigen den Mobile Safari unter iOS 11.4.1

Das wirkt zumindest, als würde es wirken:

2. Plugins

Ich setze drei Plugins mit "DSGVO-Bezug" ein:

2.1 Cookie- und Zwei-Klick-Drittinhalte-Plugin

Das Plugin Borlabs Cookie schlägt gleich zwei Fliegen mit einer Klappe:

Erstens die Opt-In-Funktion / das Cookie-Banner und die jederzeit von Betroffenen änderbaren Cookie-Einstellungen. Optionen (Texte, Cookie-Banner-Aussehen, -Platzierung, etc.) können variabel angepasst werden.

Zweitens bietet das Plugin die Option, Drittanbieter-Inhalte mit einer Zwei-Klick-Lösung zu blockieren und nur auf Wunsch nachzuladen. Das funktioniert ziemlich gut. Zusätzlich werden YouTube-Links automatisch mit dem Link zum "Erweiterten Datenschutzmodus" ersetzt.

Sollte einmal ein Drittinhalt nicht automatisch geblockt werden (z.B. die <blockquote>-Embeds von Instagram, obwohl ich nicht weiß, ob hier überhaupt Daten ausgetauscht werden), können Shortcodes eingesetzt werden.

Borlabs Cookie schlägt mit 29,- € für einzelne Webseiten zu Buche. Find ich für den Funktionsumfang ok. Auch die 149,-€-Agenturversion (auf unbegrenzt vielen Kundenprojekten einsetzbar) finde ich preislich in Ordnung. Vor allem, wenn man bedenkt, dass die ePrivacy-Verordnung ja irgendwann kommt. Vielleicht jetzt schon mal kaufen, bevor bei dem dann einsetzenden Ansturm die Preise hochgehen?

Nachtrag:
Ich nutze für eine allgemeine Einwilligung in die Datenverarbeitung gem. Datenschutzerklärung nun "GDPR Cookie Consent". Das Blocken von Inhalten Dritter regele ich über eine Eigenentwicklung.

Cookie-Banner & Drittinhalte:

Vor diesen Lösungen habe ich auch noch mit anderen Zwei-Klick-Ansätzen (Skripte und Plugins) experimentiert, das war aber immer entweder frickelig oder nicht verlässlich genug. Wer lieber ein anderes Plugin einsetzen oder selber basteln möchte, hier ein paar Anregungen:

2.2 Kommentare-Abo-Plugin

Das Plugin Subscribe to Comments Reloaded (StCR) biete die Möglichkeit eines Double-Opt-Ins und einer eigenständigen Abonnement-Verwaltung. Auch hier sind viele Optionen und Texte konfigurierbar: Alle E-Mail-Autotexte, das Aussehen und der Funktionsumfang der Abo-Verwaltungsseite, Abo-Optionen (auch Autoren-Abos möglich) …

Mehr als genug Optionen für mich und ausreichend DSGVO-konform: Abonnement mit Double-Opt-In und Verwaltung durch die Benutzenden:

2.3 Spamfilter-Plugin

Bei Antispam Bee werden in den Einstellungen alle datenschutzrelevanten Einstellungen gekennzeichnet, damit sie genauer betrachtet und deren Auswirkungen abgewogen werden können. Das sind vor allem die Überprüfung der Herkunft (via Geotargeting, Doku der Entwickler/innen hier) und der Sprache (via Google Translate, Doku der Entwickler/innen hier):

Datenschutzsensible Einstellungen von "Antispam Bee"

Da ich Google-Diensten (nicht für den Privatgebrauch, aber als Webseitenbetreiber bzgl. der Daten meiner Seitenbesuchenden) etwas skeptisch gegenüberstehe, lasse ich diese Sprachüberprüfung (vorerst) deaktiviert. Auch das Geotargeting lasse ich erst einmal aus, obwohl der genutzte Dienst ip2country an dieser Stelle eine weitere Speicherung und Verarbeitung der Daten ausschließt. Ich behalte mir allerdings – wie bereits an anderer Stelle erläutert – vor, diese Einstellungen anzupassen.

Akismet deaktiviert, Antispam Bee konfiguriert:

3. Organisatorisches: ADV-Vertrag, Verfahrensverzeichnis, Datenschutzerklärung

Mein Hoster domainfactory Serverprofis GmbH bietet einen ADV-Vordruck im Kundenmenü (Nr. 16) Kundenmenü an. Ausgefüllt, unterschrieben, zurückgeschickt:

Auch Verfahrensverzeichnis und Datenschutzerklärung waren nach dieser Artikelserie "nur" noch Schreibarbeit: Noch einmal fein säuberlich auflisten, in welchem Falle welche Daten zu welchem Zweck wie lange gespeichert werden. Eine Vorlage für das VVZ gibt es z.B. hier (LDI NRW):

Meine frisch zusammengestellte Datenschutzerklärung findet man hier:

4. Fazit

Ja, das war schon etwas Arbeit. Ich hoffe, ich hab an alles gedacht? Zumindest Untätigkeit sollte man mir nicht vorwerfen können. Dann mache ich jetzt mal – so einigermaßen DSGVO-konform – die Webseite wieder öffentlich zugänglich.

Stand: 18.07.2018, die DSGVO ist seit 54 Tagen in Anwendung 🙂

"Umsetzung der DSGVO" von Martin Smaxwil ist unter einer CC BY 4.0-Lizenz veröffentlicht.
Darüber hinausgehende Hinweise zu Bestandteilen wie Code Snippets u.ä. findet man hier.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert