Auf Datenschutz wird in Europa, gefühlt besonders in Deutschland, besonders Wert gelegt. Und ja, es gibt enorm viele schützenswerte Daten. WordPress stellt von sich aus leider keinerlei Verschlüsselung für Daten im CMS bereit. Alles was man eingibt, wird unverschlüsselt in der Datenbank gespeichert. Ok, ja, bei einem Content-Management-System geht es auch primär um ohnehin öffentliche Inhalte. Was aber, wenn es z.B. um Zugangsdaten zu AI Clients, um API-Zugänge von Zahlungsdienstleistern oder personenbezogene Angaben aus Kontaktformularen geht. Mein composer Package Crypt for WordPress soll genau hierfür ein Hilfsmittel für Plugin-Entwickler sein.
Wozu überhaupt?
Website-Inhaber sind zu vielerlei Dingen verpflichtet. Datenschutz gehört für jeden dazu. Dabei geht es jedoch nicht nur um den Schutz der Daten der zugreifenden Besucher, sondern auch um den Schutz der eigenen Daten. Nichts wäre ärgerlicher als Zugangsdaten, die man zur Verwendung eines externen Dienstes in der WordPress-Datenbank hinterlegen muss, durch einen Hack zu verlieren. Schützenswerte Daten unverschlüsselt zu speichern, ist für jeden Hacker ein willkommenes Fressen.
Auch gibt es Website-Inhaber, die durch ihre Branche oder andere Rahmenbedingungen dazu verpflichtet sind, Daten ausschließlich verschlüsselt zu speichern. Ich selbst traf im Rahmen meiner Projektumsetzungen immer wieder auf derartige Anforderungen. Dabei erfährt man z.B. vom ISO 27001 sowie ISO-27002-Standard, nach denen sich Unternehmen auch zertizieren lassen. Diese Unternehmen benötigen dann i.d.R. auch eine Website, die diesen Standard ebenfalls erfüllt. Geht das nicht, dürfen in der Website keine schützenswerten Daten gespeichert werden. Daran sind bereits Projekte gescheitert, da manches mit WordPress eben nicht möglich zu sein scheint.
Verschlüsselungsverfahren
Es gibt verschiedene Methoden um Verschlüsselungen umzusetzen. Das deutsche Bundesministerium für Sicherheit hat dazu einen Artikel bereitgestellt: https://www.bsi.bund.de/DE/Themen/Verbraucherinnen-und-Verbraucher/Informationen-und-Empfehlungen/Cyber-Sicherheitsempfehlungen/Daten-sichern-verschluesseln-und-loeschen/Datenverschluesselung/datenverschluesselung_node.html
Sie empfehlen den Einsatz des Advanced Encryption Standard (AES), was nach aktuellen Erkenntnissen der Weg ist, den man hierfür gehen sollte. Dabei wird im symmetrischen Verfahren ein Schlüssel verwendet um Inhalte zu verschlüsseln und auch zu entschlüsseln. Das entspricht übrigens ebenfalls den Vorgaben vom o.g. ISO/IEC 27002-Standard. Allerdings muss man sehr darauf bedacht sein, wo der dafür nötige Schlüssel gesichert wird. In einer öffentlich erreichbaren Umgebung wie WordPress ergeben sich daraus eine Reihe von Anforderungen.
Rahmenbedingungen bei Hostings von WordPress
WordPress besteht zum Einen aus den Dateien, zum Anderen aber auch aus der Datenbank. Die verschlüsselten Daten sollten in jedem Fall in der Datenbank abgelegt werden, damit sie schnell und performant zugreifbar sind. Bei einer symmetrischen Verschlüsselung benötigt man jedoch auch einen Schlüssel – der müsste folglich außerhalb der Datenbank abgelegt werden.
Und hier kommen bei WordPress so einige Orte in Frage:
- Die Datei
wp-config.php, wo auch die Datenbankzugangsdaten stehen. Nachteil: wer diese Datei hat, hat sowohl Zugriff auf die Datenbank als auch den Schlüssel, müsste lediglich den Zusammenhang erkennen, wüsste aber nicht adhoc welche Daten verschlüsselt sind. - Ein individuelles Plugin, welches den Schlüssel bereithält.
- Ein Must-Use-Plugin könnte das ebenfalls übernehmen.
- Eine Datei abseits von WordPress, die einfach im Hosting abgelegt wird (vlt. außerhalb des Web-Verzeichnisses) und auf die sich die Methode zum Entschlüsseln beziehen kann.
- Umgebungsvariablen, die man im Hosting hinterlegt und auf die ein Code in WordPress zugreifen kann. Nachteile: für normale Anwender schwer umsetzbar, auch ist es nicht in jedem Hosting möglich (und bei nginx Webservern gleich mal gar nicht).
Eine Herausforderung bei all diesen Möglichkeiten sind die Hostings, in denen WordPress genutzt werden kann. Es gibt Hoster, wie WPEngine und Raidboxes, die es nicht ermöglichen die wp-config.php durch Programmierungen anzupassen. Es gibt auch Hoster, die die Schreibrechte im wp-content beschränken oder bei denen man außerhalb des Web-Verzeichnisses gar nichts machen darf. Für einfache Anwender kann die Einrichtung einer Verschlüsselung daher eine Herausforderung sein, weshalb die Verwendung von Verschlüsselungen in WordPress sowohl anwenderfreundlich und möglichst sicher gleichzeitig gedacht werden muss.
Crypt for WordPress verwenden
Aus all diesen Gründen habe ich das Composer Package Crypt for WordPress entwickelt. Es stellt die Möglichkeit bereit Texte (aka Strings) zu verschlüsseln und zu entschlüsseln. Es nutzt, ohne weitere Konfiguration, die aktuell Besten und vom Hosting unterstützten Verschlüsselungsmethoden und schreibt den Schlüssel an die erstbeste Stelle, die vom Hosting unterstützt wird. Diese Entscheidungen kann man jedoch auch konfigurieren.
Einfaches Beispiel:
$crypt = new Crypt( __FILE__ );
echo $crypt->encrypt( 'Hallo Welt' );
Hier wird einfach nur das Crypt-Objekt geladen und ein Text verschlüsselt – fertig :)
Über die Methode set_config() kann man die Bibliothek konfigurieren. Für die beiden unterstützten Verschlüsselungsmethoden OpenSSL und Sodium ist es möglich, jeweils eigene Einstellungen zu hinterlegen. Z.B. kann man den zu verwendeten Hash-Typ an die eigenen Wünsche anpassen.
Schlüssel-Handling
Beim allerersten Aufruf der Bibliothek in einem Projekt, passiert folgendes:
- Prüfung, ob schon ein Schlüssel hinterlegt ist.
- Wenn nein, wird dieser erst- und einmalig erzeugt.
- Danach wird geschaut, welche Stelle (Place) in dem Hosting für den Schlüssel am besten geeignet ist. Diese Prüfung geschieht in folgender Reihenfolge:
- Ist die
wp-config.phpbeschreibbar, wird diese verwendet. - Kann ein MU-Plugin gespeichert werden, wird dieses dynamisch erzeugt und gespeichert.
- Nur, wenn eine Konfiguration dazu hinterlegt ist, wird als letzte Möglichkeit ein individueller Pfad zum Speichern verwendet.
- Ist die
- Anschließend wird der Schlüssel in der ermittelten Stelle gespeichert.
- Bei jedem weiteren Aufruf, wird der Schlüssel automatisch geladen und steht somit zur Verfügung.
Das Plugin speichert den Schlüssel als PHP-Konstante, die dann bei jedem Ladevorgang überall zur Verfügung steht. Diese PHP-Konstante wird dynamisch nach der aufrufenden WordPress-Komponente (Plugin oder Theme) benannt, wodurch in einem Projekt durchaus auch mehrere Schlüssel von verschiedenen Komponenten hinterlegt sein könnten. Dadurch ist es z.B. nicht möglich, dass Plugin A die Daten von Plugin B entschlüsselt und verwendet.
OpenSSL vs. Sodium
Diese beiden Komponenten können in in aktuellen PHP-Versionen i.d.R. zur Verschlüsselung genutzt werden. OpenSSL ist schon länger dabei, Sodium seit PHP 7.2 immer enthalten. Es gibt Hostings die durchaus eine von beiden Komponenten deaktiviert haben, daher beachte ich mit meiner Bibliothek Crypt for WordPress beide.
Mit dem Parameter ‚force_method‘ in o.g. Konfiguration kann man eine der beiden Komponenten erzwingen. Wenn man das in einem eigenen Plugin einsetzt, muss man jedoch bedenken, dass es dann durchaus Anwender geben könnte, die die von dir bevorzugte Komponente nicht im Hosting zur Verfügung haben. In dem Fall würde dann keine Verschlüsselung erfolgen. Es ist daher durchaus besser die Entscheidung der Bibliothek zu überlassen.
Crypt for WordPress nutzt bei OpenSSL z.B. eine kryptographische Zufallsgenerierung für jeden Vorgang. Das erschwert zusätzlich zum Einsatz des Schlüssels das Entschlüsseln der Strings.
Anwendungsfälle
Ich verwende Crypt for WordPress bereits bei mehreren meiner eigenen Plugins. Bei Personio Integration werden damit z.B. jegliche Daten von Bewerbern in der Datenbank verschlüsselt gespeichert. Bei ProvenExpert und Externe Dateien in der Mediathek werden jeweils die API-Zugangsdaten verschlüsselt. Als Anwender der Plugins merkt man es gar nicht. Die Bibliothek kümmert sich still und leise im Hintergrund um alles.
Mit WordPress 7.0 wurde der AI Client in das CMS integriert. Dadurch können Nutzer ihre API-Schlüssel für den Zugriff auf KI-Dienste an einem zentralen Ort im Backend speichern. Diese Schlüssel werden jedoch unverschlüsselt in der Datenbank gespeichert, was für manche Projekte ein Ausschlusskriterium für die Verwendung von API-Schlüsseln im AI Client darstellt. Mit Encrypt AI Connector Keys habe ich ein Plugin bereitgestellt, welches diese API Keys dank Crypt for WordPress verschlüsselt.
Verschlüsselungen individualisieren
Die Bibliothek Crypt for WordPress liefert derzeit 6 Hooks mit. Diese sind an den Slug der aufrufenden Komponente gebunden und ermöglichen z.B. die Beeinflussung der verfügbaren Verschlüsselungsmethoden, der Stellen zum Speichern des Schlüssels und der Bezeichnung der Konstanten. Sollte euer Projekt die wp-config.php unter einem anderen Namen verwenden (ja, das geht) oder einem anderen Pfad als üblich gespeichert sein, dann kann man auch das über einen Hook mitteilen.
Fazit
Gerne könnt ihr Crypt for WordPress für eure eigenen Plugins verwenden. Es ist heute bereits extrem stabil und wird, wie man an den Nutzerzahlen der o.g. Plugins sehen kann, bereits von tausenden Nutzern problemlos eingesetzt. Die Installationsanleitung findet ihr hier. Ich stelle auch ein Demo-Plugin bereit, wo ihr euch das kurz selbst anschauen könnt.