Sec Bug->Bug #72963 [Opn]: Null-byte injection in createFromFormat

From: Date: Fri, 02 Sep 2016 04:57:55 +0000
Subject: Sec Bug->Bug #72963 [Opn]: Null-byte injection in createFromFormat
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-203742@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72963&edit=1 ID: 72963 Updated by: stas@php.net Reported by: qoqe at inbox dot lv Summary: Null-byte injection in createFromFormat Status: Open -Type: Security +Type: Bug Package: Date/time related Operating System: Linux, Windows PHP Version: 7.0.10 -Assigned To: +Assigned To: derick Block user comment: N Private report: Y Previous Comments: ------------------------------------------------------------------------ [2016-08-29 11:24:24] qoqe at inbox dot lv Description: ------------ createFromFormat method from DateTime class is sensitive to null-byte injection. According to best practices to verify if date is valid in PHP, the best way is to use DateTime::createFromFormat because it returns false if date isn't valid. This way to verify date is used in many CMS systems (for example, in Drupal). The problem is that DateTime::createFromFormat second parameter is vulnerable to null-byte which can be passed to it when createFromFormat method is used to verify GET or POST param. Here are results if application calls DateTime::createFromFormat('m/d/Y', $_GET['startFrom']); where startFrom=8/8/2016 - will return true startFrom=8/8/2016asd - will return false startFrom=8/8/2016%00asd - will return true It seems to be reliable verification if date is valid and developer might not use htmlspecialchars or real_escape_string after it. This may lead to SQL Injection or XSS. Test script: --------------- <?php function verifyDate($date, $strict = true) { $dateTime = DateTime::createFromFormat('m/d/Y', $date); if ($strict) { $errors = DateTime::getLastErrors(); if (!empty($errors['warning_count'])) { return false; } } return $dateTime !== false; } if(!empty($_GET['startFrom']) && verifyDate($_GET['startFrom'])) { // query to database without escaping $_GET['startFrom'] // because it has passed verification of valid date } // tests var_dump(verifyDate('asd')); // false var_dump(verifyDate('8/8/2016')); // true var_dump(verifyDate('8/8/2016asdasd')); // false var_dump(verifyDate("8/8/2016\x00asdasd")); // true ?> ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72963&edit=1

« previous php.bugs (#203742) next »