{"id":636,"date":"2012-10-01T11:00:35","date_gmt":"2012-10-01T09:00:35","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=636"},"modified":"2016-01-11T23:52:11","modified_gmt":"2016-01-11T22:52:11","slug":"htmlspecialchars-richtig-nutzen-fallstricke","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/htmlspecialchars-richtig-nutzen-fallstricke\/","title":{"rendered":"htmlspecialchars richtig nutzen &#8211; Fallstricke"},"content":{"rendered":"<p>In der PHP-Welt scheint der Mythos vorzuherrschen, dass die Nutzung von htmlspecialchars s\u00e4mtlichen Input in s\u00e4mtlichen Situation sicher macht. Quasi die &#8222;one fits all&#8220; &#8211; Funktion. Beginnen wir gleich mal mit einem Beispiel. Kein Witz, so gesehen:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\nfunction get_user_id($db)\r\n{\r\n\t$username = htmlspecialchars(trim($_POST[&#039;username&#039;]));\r\n\t$res = $db-&gt;query(&quot;SELECT `id` FROM `accounts` WHERE `login` = &#039;$username&#039; LIMIT 1&quot;);\r\n\treturn $res[0][&#039;id&#039;];\r\n}\r\n<\/pre>\n<p>Cool! Schauen wir uns doch mal die Signatur von <a href=\"http:\/\/php.net\/manual\/de\/function.htmlspecialchars.php\">htmlspecialchars<\/a> an:<\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">\r\nstring htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = &#039;UTF-8&#039; [, bool $double_encode = true ]]] )\r\n<\/pre>\n<h2>Das verflixte Hochkomma<\/h2>\n<p>Besonderes Augenmerk sei auf die Flags gelegt. <b>ENT_COMPAT <\/b> hei\u00dft &#8222;<i>Konvertiert nur doppelte Anf\u00fchrungszeichen und l\u00e4sst einfache Anf\u00fchrungszeichen unver\u00e4ndert.<\/i>&#8222;. Also: Perfektes Einfallstor f\u00fcr SQL-Injection.<\/p>\n<p>Gleiches ergibt sich im Formularhandling:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n&lt;?php\r\n$_GET[&#039;firstname&#039;] = &quot;&#039;onmouseover=&#039;alert(\/xss!\/)&#039;&quot;;\r\n$firstname = htmlspecialchars($_GET[&#039;firstname&#039;], ENT_COMPAT);\r\n?&gt;\r\n&lt;input name=&#039;firstname&#039; value=&#039;&lt;?php echo $firstname ?&gt;&#039;&gt;\r\n<\/pre>\n<p>Analog zu diesem <a href=\"https:\/\/d-mueller.de\/blog\/php-wtf-8\/\">PHP WTF<\/a>-Artikel erfreut auch hier die !sinnvolle Wahl der Defaultparameter. Der Flags-Parameter sollte also in jedem Fall <b>ENT_QUOTES<\/b> enthalten, so werden n\u00e4mlich auch Single-Quotes durch das entsprechende Pendant <i>&amp;#039;<\/i> ersetzt. <\/p>\n<h2>Encoding<\/h2>\n<p>Seit PHP 5.4 ist der dritte Parameter <i>string $encoding<\/i> sinnvollerweise auf UTF-8 gesetzt. Vorher kam htmlspecialchars mit <i>ISO-8859-1<\/i> als Standard daher. Bei der Frage des Encodings gilt: <b>Immer dasselbe Encoding verwenden, das auch die Applikation selbst verwendet<\/b>. Und das sollte ja in der Regel UTF-8 sein. Deswegen in Libraries am Besten eine eigene Wrapperfunktion bauen, die genau so aussieht:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\nfunction real_htmlspecialchars($string)\r\n{\r\n\treturn htmlspecialchars($string, ENT_QUOTES, &quot;UTF-8&quot;);\r\n}\r\n<\/pre>\n<p>Und trotz dessen: F\u00fcr Datenbankparameter ist htmlspecialchars tabu! PDO bietet die <a href=\"http:\/\/php.net\/manual\/de\/pdo.quote.php\">quote<\/a>-Funktion und wer wirklich noch mit nacktem MySQL rumjuckeln muss freut sich \u00fcber <a href=\"http:\/\/php.net\/manual\/de\/function.mysql-real-escape-string.php\">mysql_real_escape_string<\/a> oder alterantiv die Escape-Funktion des verwendeten Frameworks.<\/p>\n<p>Interessant auch, wie es &#8222;die Gro\u00dfen&#8220; betreiben: Die u.a. von Symfony verwendete Template-Engine <a href=\"https:\/\/raw.github.com\/fabpot\/Twig\/master\/lib\/Twig\/Extension\/Core.php\">Twig (siehe <i>twig_escape_filter<\/i>)<\/a> und der <a href=\"https:\/\/raw.github.com\/zendframework\/zf2\/master\/library\/Zend\/Escaper\/Escaper.php\">Zend-Escaper<\/a> kann man sich mal zu Gem\u00fcte f\u00fchren. Sehr lesenswert ist auch das <a href=\"https:\/\/gist.github.com\/3066656\">eingereichte Proposal<\/a> f\u00fcr einen vern\u00fcnftigen, kontextabh\u00e4ngigen PHP-builtin-Escaper.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In der PHP-Welt scheint der Mythos vorzuherrschen, dass die Nutzung von htmlspecialchars s\u00e4mtlichen Input in s\u00e4mtlichen Situation sicher macht. Quasi die &#8222;one fits all&#8220; &#8211; Funktion. Beginnen wir gleich mal mit einem Beispiel. Kein Witz, so gesehen: function get_user_id($db) { &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/htmlspecialchars-richtig-nutzen-fallstricke\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,6,3],"tags":[],"class_list":["post-636","post","type-post","status-publish","format-standard","hentry","category-php","category-security","category-webdev"],"_links":{"self":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/636","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/comments?post=636"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/636\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=636"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}