htmlspecialchars richtig nutzen – Fallstricke

In der PHP-Welt scheint der Mythos vorzuherrschen, dass die Nutzung von htmlspecialchars sämtlichen Input in sämtlichen Situation sicher macht. Quasi die „one fits all“ – Funktion. Beginnen wir gleich mal mit einem Beispiel. Kein Witz, so gesehen:

function get_user_id($db)
{
	$username = htmlspecialchars(trim($_POST['username']));
	$res = $db->query("SELECT `id` FROM `accounts` WHERE `login` = '$username' LIMIT 1");
	return $res[0]['id'];
}

Cool! Schauen wir uns doch mal die Signatur von htmlspecialchars an:

string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = 'UTF-8' [, bool $double_encode = true ]]] )

Das verflixte Hochkomma

Besonderes Augenmerk sei auf die Flags gelegt. ENT_COMPAT heißt „Konvertiert nur doppelte Anführungszeichen und lässt einfache Anführungszeichen unverändert.„. Also: Perfektes Einfallstor für SQL-Injection.

Gleiches ergibt sich im Formularhandling:

<?php
$_GET['firstname'] = "'onmouseover='alert(/xss!/)'";
$firstname = htmlspecialchars($_GET['firstname'], ENT_COMPAT);
?>
<input name='firstname' value='<?php echo $firstname ?>'>

Analog zu diesem PHP WTF-Artikel erfreut auch hier die !sinnvolle Wahl der Defaultparameter. Der Flags-Parameter sollte also in jedem Fall ENT_QUOTES enthalten, so werden nämlich auch Single-Quotes durch das entsprechende Pendant &#039; ersetzt.

Encoding

Seit PHP 5.4 ist der dritte Parameter string $encoding sinnvollerweise auf UTF-8 gesetzt. Vorher kam htmlspecialchars mit ISO-8859-1 als Standard daher. Bei der Frage des Encodings gilt: Immer dasselbe Encoding verwenden, das auch die Applikation selbst verwendet. Und das sollte ja in der Regel UTF-8 sein. Deswegen in Libraries am Besten eine eigene Wrapperfunktion bauen, die genau so aussieht:

function real_htmlspecialchars($string)
{
	return htmlspecialchars($string, ENT_QUOTES, "UTF-8");
}

Und trotz dessen: Für Datenbankparameter ist htmlspecialchars tabu! PDO bietet die quote-Funktion und wer wirklich noch mit nacktem MySQL rumjuckeln muss freut sich über mysql_real_escape_string oder alterantiv die Escape-Funktion des verwendeten Frameworks.

Interessant auch, wie es „die Großen“ betreiben: Die u.a. von Symfony verwendete Template-Engine Twig (siehe twig_escape_filter) und der Zend-Escaper kann man sich mal zu Gemüte führen. Sehr lesenswert ist auch das eingereichte Proposal für einen vernünftigen, kontextabhängigen PHP-builtin-Escaper.

Weitere Posts:

Dieser Beitrag wurde unter php, Security, webdev veröffentlicht. Setze ein Lesezeichen auf den Permalink.

4 Antworten auf htmlspecialchars richtig nutzen – Fallstricke

  1. Boje-a sagt:

    Als Anfänger bin ich gerade dabei mich einzuarbeiten. Es wäre für mich sehr hilfreich, wenn Sie mir erklären könnten oder mitteilen könnten wo ich eine Erklärung dafür finden könnte, was folgender Code bedeutet:
    $content = explode(‚/‘, htmlspecialchars($_GET[‚c‘]));

    • david sagt:

      Macht den per URL?c=abc/def/ghi übermittelten Querystring zu einem Array [„abc“, „def“, „ghi“]

      • nk sagt:

        Viel taugen tut das aber nicht. Queryparameter könne ja problemlos Arrays übergeben. Wenn der Wert aus einem Select kommt, ist es besser, über das Select nur den ZUgriffsschlüssel auf den eigentlichen Datensatz zu übergeben.

  2. Nico sagt:

    Super Sache.. Ich habe mich auch schon oft gewundert .. mittlerweile verwende ich ENT_QUOTES standardmäßig, um SQL Injections vorzubeugen.

Schreibe einen Kommentar

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