Edit report at https://bugs.php.net/bug.php?id=72963&edit=1
ID: 72963
Updated by: derick@php.net
Reported by: qoqe at inbox dot lv
Summary: Null-byte injection in createFromFormat
Status: Assigned
Type: Bug
Package: Date/time related
Operating System: Linux, Windows
PHP Version: 7.0.10
Assigned To: derick
Block user comment: N
Private report: N
New Comment:
https://github.com/php/php-src/pull/8593
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