Schwachstellen in Webanwendungen – Teil 2

In Teil 1 wurden zwei der drei häufigsten Schwachstellen in Webanwendungen beschrieben. Die von der OWASP am häufigsten genannte Schwachstelle ist Code-Injection. Hierbei handelt es sich um Schwachstellen die durch den Einsatz von Interpretern hervorgerufen werden. Auf Platz drei ist die Cross-Site-Scripting (XSS) Schwachstelle. In diesem Teil werden Lösungsansätze für die Entwicklung von WordPress-Themes und -Plugins vorgestellt.

Nutze die Macht der Prepared Statements

Schwachstellen in WordPress-Themes und -PluginsBei der Entwicklung von Plugins sind unterumständen selbstdefinierte Datenbankabfragen notwendig. Datenbankmanagementsysteme (DBMS) sind sehr anfällig für Code-Injection-Angriffe. Moderne DBMS bieten eine Funktion, Prepared Statement genannt, an. Prepared Statements trennen die Abfragen von den übergebenen Werten. Zuerst wird ein Statement mit Platzhaltern an das DBMS übergeben. Im zweiten Schritt werden dann die Platzhalter durch die gewünschten Werte ersetzt. Die Trennung in zwei Schritte sorgt dafür, dass übergebene Werte nicht mehr Interpretiert werden, sondern wie erwartet nur als Werte verstanden werden. Weiterhin werden die Statements im Cache vorgehalten und lassen sich so wiederholt und mit einem Performancegewinn ausführen.

WordPress nutzt MySQL als DBMS. Bedingt durch den Verwandtheitsgrad zwischen MySQL und MariaDB, lässt sich auch letzteres DBMS mit WordPress problemlos verwenden.

Prepared Statements mit PHP

Hier ein Beispiel, wie das ganze objektorientiert umsetzbar ist. Hierbei wird die MySQLi-Treiberklasse genutzt:

 
$id = 1;
$mysqli = new mysqli("host", "username", "password", "database"); // create connection
$stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"); // create pepared-statement
$stmt->bind_param("i", $id); // bind param to statement
$stmt->execute(); // execute query with binded param and current value
$stmt->close(); // close statement
$mysqli->close(); // close connection to database

Alternativ kann dies natürlich auch mit dem ODBC-Treiber genutzt werden. Die Funktionsweise beim ODBC-Treiber ist äquivalent zu der Nutzung bei der MySQLi-Treiberklasse.

Prepared Statements mit wpdb

WordPress bietet eine statische Methode aus der klasse wpdb an, die für die Abfrage genutzt werden kann, falls benötigt.


$wpdb->prepare( "SELECT id FROM wp_posts WHERE id > %d", $min_id); // Alle Posts mit der ID größer $min_id

Die Methode wpdb::prepare( string $query, array|mixed $args ) unterstützt die Platzhalter %d(Ganzzahlen), %f(Fließkomma) und %s(Zeichenketten). Um ein Prozentzeichen in der Abfrage zu nutzen, ist das Zeichenpaar %% notwendig.
Weitere Ausführung sind auf der Developer-Seite von WordPress zu finden.

Filter die Ein- und Ausgaben

Cross-Site-Scripting ist eine echt nervige Sache und schwierig die fehlerbehaftete Implementierung nachträglich aufzudecken. Deshalb sollte direkt zu beginn darauf geachtet werden, dass Eingaben validiert und hauptsächlich die Ausgaben gefiltert werden.

htmlentities()

PHP bietet für das Filter von Ausgaben die Funktion htmlentities an. Die Funktion wandelt alle geeigneten Zeichen in entsprechende HTML-Codes um.


echo htmlentities("Hallo 'Jonas'", ENT_QUOTES); // Doppelte und einfache Anführungszeichen werden konvertiert
// Ausgabe: Hallo 'Jonas'

Die Maskierung mit htmlentities bezieht sich nur auf HTML. Wird die Ausgabe in einen JavaScript-Block geschrieben, um diesen dann anschließend auszuführen, ist eine entsprechende Methode zu nutzen. Derzeit ist die Möglichkeit zur Maskierung mittels json_encode zu empfehlen.


json_encode("'abc'", JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE); // Alle relevanten Zeichen maskieren
// Ausgabe: \u0027bar\u0027

WordPress Spezialmethoden

WordPress stellt ein paar Methoden für das maskieren von Ausgaben bereits in den Core-Functions bereit. Diese sollten bereits bei der Entwicklung berücksichtigt und eingesetzt werden, das erspart einem unnötiges suchen und ersetzten im Nachgang.


esc_html() // Maskierung von HTML
esc_url() // Maskierung von Attributen
esc_js() // Maskierung von JavaScript
esc_attr() // Maskierung von Attributen in HTML-Tags (bsp. class)
esc_textarea() // Maskierung von Text, der für Textareas gedacht ist

Eine Übersicht über die Funktionen und weitere Information dazu, sind im WordPress-Codex zu finden. Viele WordPress-Funktionen führen bereits eine Maskierung der Ausgaben durch. Als Beispiel ist die Funktion the_title() zu nennen. Eine erneute Maskierung ist bei diesen Funktionen nicht notwendig.

Fazit

Die Sicherheit von WordPress-Plugins und -Themes liegt in der Hand der jeweiligen Entwickler und kann nicht durch den WordPress-Core abgefangen werden. Um es jedoch den Entwicklern zu erleichtern, für mehr Sicherheit zu sorgen, werden einige sinnvolle Funktion bereitgestellt. Jetzt liegt es an einem selbst die Funktionen zu nutzen und zur Sicherheit des CMS beizutragen.

Jonas

Jonas macht gerade seinen Bachelor of Science im Bereich Wirtschaftsinformatik und arbeitet seit 2015 auf selbstständiger Basis als Webentwickler mit Schwerpunkt individueller Webanwendungen. Von 2011 bis 2014 hat er eine Ausbildung als Fachinformatiker gemacht. Seit 2014 ist er bei einer deutschen Versicherung im IT-Bereich tätig. Von Linux bis Owncloud und von .NET bis Swift gibt es viele Themengebiete, die sein Interesse wecken.

Schreibe einen Kommentar

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