{"id":464,"date":"2011-01-04T19:44:11","date_gmt":"2011-01-04T18:44:11","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=464"},"modified":"2011-01-06T23:14:05","modified_gmt":"2011-01-06T22:14:05","slug":"fieser-bug-in-php-5-3","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/fieser-bug-in-php-5-3\/","title":{"rendered":"fieser Bug in PHP 5.3 [Update]"},"content":{"rendered":"<p>Man stelle sich folgenden Quellcode in einem Onlinebanking-Formular vor:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n&lt;?php\r\nif (!empty($_POST[&#039;ueberweisungsbetrag&#039;]) &amp;&amp; filter_var($_POST[&#039;ueberweisungsbetrag&#039;], FILTER_VALIDATE_FLOAT)!==false)\r\n{\r\n    $ueberweisungsbetrag = $_POST[&#039;ueberweisungsbetrag&#039;];\r\n}\r\nelse\r\n{\r\n    $ueberweisungsbetrag = 0;\r\n}\r\n?&gt;\r\n&lt;input type=&quot;text&quot; name=&quot;ueberweisungsbetrag&quot; value=&quot;&lt;?php echo $ueberweisungsbetrag; ?&gt;&quot; \/&gt;\r\n<\/pre>\n<p>Sieht ja eigentlich erstmal ganz vern\u00fcnftig aus, oder? Validierung des einigegebenen $_POST-Betrags, um dem Benutzer bei einem Fehler das erneute eintippen zu ersparen. Wenn man nun allerdings die verdammt kleine Gleitkommazahl <b>2.2250738585072011e-308<\/b> als Betrag eintippt, hat das den gleichen Effekt wie<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\nwhile (true) {}\r\n<\/pre>\n<p>N\u00e4mlich: <b>Fatal error: Maximum execution time of 30 seconds exceeded in \/var\/www\/test.php on line 3<\/b>. Diese omin\u00f6se Zahl f\u00fchrt also PHP-intern zu einem verrecken des Scripts. Das passiert immer, wenn die Zahl auch wirklich als <b>Zahl interpretiert wird<\/b>.<\/p>\n<p>Hei\u00dft:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\nprint $_GET[&#039;floatval&#039;]; \/\/ doc.php?floatval=2.2250738585072011e-308 -&gt; no problem - treated as string\r\nprint &quot;2.2250738585072011e-308&quot;; \/\/ no problem - string\r\nprint 2.2250738585072011e-308; \/\/crash!\r\nprint &quot;2.2250738585072011e-308&quot;*1; \/\/ crash!\r\nprint (float)&quot;2.2250738585072011e-308&quot;; \/\/ crash!\r\nfilter_var(&quot;2.2250738585072011e-308&quot;, FILTER_VALIDATE_FLOAT); \/\/ crash!\r\n<\/pre>\n<p>Wenn irgendwo also $_GET-Variablen validiert werden (=als Zahl interpretiert werden), k\u00f6nnte man so recht billig eine <b>DoS-Attacke<\/b> fahren.<br \/>\nEs muss \u00fcbrigens genau diese Zahl sein, bei einer minimalen Abwandlung geht alles gut. Es ist auch nur die 32 Bit Version betroffen. Bei meinen Tests unter Ubuntu (PHP Version 5.3.3-1) und Windows XAMPP (PHP Version 5.3.1) war das wunderbar reproduzierbar. Laut <a href=\"http:\/\/www.golem.de\/1101\/80463.html\">Golem<\/a> seien die PHP-Versionen 5.3.3-6, 5.3.2-1 und 5.3.1 betroffen. Ein Update gibt es noch nicht (Stand: 04.01.<s>2010<\/s> 2011 &#8211; <i>mit Dank an den Klugschei\u00dfer in den Kommentaren ;)<\/i>).\n<\/p>\n<p>Es gibt bereits ein <a href=\"http:\/\/bugs.php.net\/bug.php?id=53632\">PHP-Bug-Ticket<\/a> dazu, gefunden hat den Bug <a href=\"http:\/\/www.exploringbinary.com\/php-hangs-on-numeric-value-2-2250738585072011e-308\/\">dieser Blogger<\/a>.<\/p>\n<h3>[Update 06.01.2011]<\/h3>\n<p>Bei den <a href=\"http:\/\/news.ycombinator.com\/item?id=2066084\">Hacker News<\/a> gabs eine interessante Diskussion, die auch folgenden Kommentar hervorbrachte:<\/p>\n<blockquote><p>\nThis is the nature of floating point numbers: they&#8217;re not exactually [sic] &#8222;exact&#8220; at all. Converting a fixed fraction decimal number into a floating point means turning an exact number into its best approximation. In order to get the approximation as close as possible to the original number, a floating point conversion algorithm will perform several runs until the error between the original number and the floating point representation is smaller than some very small value. This leads to problems when either the error can&#8217;t get smaller than the required precision, or when the error doesn&#8217;t decrease per iteration. In both cases an algorithm that doesn&#8217;t have error detection will be stuck in an infinite loop.\n<\/p><\/blockquote>\n<p>Laut Johannes Schl\u00fcter sind \u00fcbrigens auch alte PHP-Versionen bis runter zur 3.0 betroffen. F\u00fcr die aktuelleren 5.3 und 5.2 Zweige wurden jeweils aktualisierte Versionen (5.3.5 bzw. 5.2.17) released, die diesen Bug beheben. Auf \u00e4lteren Versionen muss mit <i>-mfpmath=sse<\/i> bzw. <i>-ffloat-store<\/i> PHP neu kompiliert werden. \u00dcbrigens sind laut <a href=\"http:\/\/www.zend.com\/en\/company\/news\/news-links\/php-remote-exploit-information-and-hotfix\">Zend<\/a> nur die 32Bit-Versionen von Linux befallen, unter Windows jedoch 32Bit und 64Bit-Builds.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Man stelle sich folgenden Quellcode in einem Onlinebanking-Formular vor: &lt;?php if (!empty($_POST[&#039;ueberweisungsbetrag&#039;]) &amp;&amp; filter_var($_POST[&#039;ueberweisungsbetrag&#039;], FILTER_VALIDATE_FLOAT)!==false) { $ueberweisungsbetrag = $_POST[&#039;ueberweisungsbetrag&#039;]; } else { $ueberweisungsbetrag = 0; } ?&gt; &lt;input type=&quot;text&quot; name=&quot;ueberweisungsbetrag&quot; value=&quot;&lt;?php echo $ueberweisungsbetrag; ?&gt;&quot; \/&gt; Sieht ja eigentlich erstmal ganz &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/fieser-bug-in-php-5-3\/\">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-464","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\/464","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=464"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/464\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=464"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=464"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=464"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}