From f8deea583f0cb68a83a44d361c0db3c86f387f95 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 23 Oct 2015 13:49:21 +0300 Subject: Use proper randomness when generating CAPTCHAs --- system/helpers/captcha_helper.php | 89 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 201987ac8..85bcfb5a0 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -125,9 +125,94 @@ if ( ! function_exists('create_captcha')) if (empty($word)) { $word = ''; - for ($i = 0, $mt_rand_max = strlen($pool) - 1; $i < $word_length; $i++) + $pool_length = strlen($pool); + $rand_max = $pool_length - 1; + + // PHP7 or a suitable polyfill + if (function_exists('random_int')) + { + try + { + for ($i = 0; $i < $word_length; $i++) + { + $word .= $pool[random_int(0, $rand_max)]; + } + } + catch (Exception $e) + { + // This means fallback to the next possible + // alternative to random_int() + $word = ''; + } + } + } + + if (empty($word)) + { + // Nobody will have a larger character pool than + // 256 characters, but let's handle it just in case ... + // + // No, I do not care that the fallback to mt_rand() can + // handle it; if you trigger this, you're very obviously + // trying to break it. -- Narf + if ($pool_length > 256) + { + return FALSE; + } + + // We'll try using the operating system's PRNG first, + // which we can access through CI_Security::get_random_bytes() + $security = get_instance()->security; + + // To avoid numerous get_random_bytes() calls, we'll + // just try fetching as much bytes as we need at once. + if (($bytes = $security->get_random_bytes($pool_length)) !== FALSE) + { + $byte_index = $word_index = 0; + while ($word_index < $word_length) + { + if (($rand_index = unpack('C', $bytes[$byte_index++])) > $rand_max) + { + // Was this the last byte we have? + // If so, try to fetch more. + if ($byte_index === $pool_length) + { + // No failures should be possible if + // the first get_random_bytes() call + // didn't return FALSE, but still ... + for ($i = 0; $i < 5; $i++) + { + if (($bytes = $security->get_random_bytes($pool_length)) === FALSE) + { + continue; + } + + $byte_index = 0; + break; + } + + if ($bytes === FALSE) + { + // Sadly, this means fallback to mt_rand() + $word = ''; + break; + } + } + + continue; + } + + $word .= $pool[$rand_index]; + $word_index++; + } + } + } + + if (empty($word)) + { + for ($i = 0; $i < $word_length; $i++) { - $word .= $pool[mt_rand(0, $mt_rand_max)]; + $word .= $pool[mt_rand(0, $rand_max)]; } } elseif ( ! is_string($word)) -- cgit v1.2.3-24-g4f1b From 2fe1a2389aa13c3acde7fb42ab35e79504e89f75 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 9 Nov 2015 11:24:19 +0200 Subject: [ci skip] Fix an infinite loop in captcha helper --- system/helpers/captcha_helper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 85bcfb5a0..03c1dd852 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -171,7 +171,8 @@ if ( ! function_exists('create_captcha')) $byte_index = $word_index = 0; while ($word_index < $word_length) { - if (($rand_index = unpack('C', $bytes[$byte_index++])) > $rand_max) + list(, $rand_index) = unpack('C', $bytes[$byte_index++]); + if ($rand_index > $rand_max) { // Was this the last byte we have? // If so, try to fetch more. -- cgit v1.2.3-24-g4f1b From 6a7a16073aefbc0bff0fb850d97ea11c57d693c1 Mon Sep 17 00:00:00 2001 From: dimitribalazs Date: Wed, 18 Nov 2015 11:50:22 +0100 Subject: Added alt attribute functionality … MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It hasn't been possible to set the alt attribute on the image. Added img_alt key on the $defaults array and integrated the $img_alt variable into the img string. --- system/helpers/captcha_helper.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 85bcfb5a0..3cf581bba 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -79,7 +79,8 @@ if ( ! function_exists('create_captcha')) 'border' => array(153,102,102), 'text' => array(204,153,153), 'grid' => array(255,182,182) - ) + ), + 'img_alt' => 'captcha' ); foreach ($defaults as $key => $val) @@ -330,7 +331,7 @@ if ( ! function_exists('create_captcha')) return FALSE; } - $img = ' '; + $img = ''.$img_alt.''; ImageDestroy($im); return array('word' => $word, 'time' => $now, 'image' => $img, 'filename' => $img_filename); -- cgit v1.2.3-24-g4f1b From 125ef4751080a2118cb203357d77687699e3eb25 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 11 Jan 2016 12:33:00 +0200 Subject: [ci skip] Bump year to 2016 --- system/helpers/captcha_helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 03c1dd852..4d8e98ea6 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 1.0.0 -- cgit v1.2.3-24-g4f1b From bd202c91b0e9cf0a8c93bcaa71df9574f5909346 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 11 Jan 2016 12:50:18 +0200 Subject: [ci skip] Update codeigniter.com links to https --- system/helpers/captcha_helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 4d8e98ea6..db708e894 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 1.0.0 * @filesource */ @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Helpers * @category Helpers * @author EllisLab Dev Team - * @link http://codeigniter.com/user_guide/helpers/captcha_helper.html + * @link https://codeigniter.com/user_guide/helpers/captcha_helper.html */ // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 1924e879b165fb119847a49a7a5eab2f28295fa2 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 11 Jan 2016 12:55:34 +0200 Subject: [ci skip] Update ellislab.com links to https too --- system/helpers/captcha_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index db708e894..fd1b8f1ed 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com -- cgit v1.2.3-24-g4f1b From ec9e96eb09caa9d024c89a8bdb1b00bf6540278a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 4 Feb 2016 14:43:46 +0200 Subject: Fix #4427 --- system/helpers/captcha_helper.php | 45 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index fd1b8f1ed..3c1e006f8 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -171,35 +171,36 @@ if ( ! function_exists('create_captcha')) $byte_index = $word_index = 0; while ($word_index < $word_length) { - list(, $rand_index) = unpack('C', $bytes[$byte_index++]); - if ($rand_index > $rand_max) + // Do we have more random data to use? + // It could be exhausted by previous iterations + // ignoring bytes higher than $rand_max. + if ($byte_index === $pool_length) { - // Was this the last byte we have? - // If so, try to fetch more. - if ($byte_index === $pool_length) + // No failures should be possible if the + // first get_random_bytes() call didn't + // return FALSE, but still ... + for ($i = 0; $i < 5; $i++) { - // No failures should be possible if - // the first get_random_bytes() call - // didn't return FALSE, but still ... - for ($i = 0; $i < 5; $i++) + if (($bytes = $security->get_random_bytes($pool_length)) === FALSE) { - if (($bytes = $security->get_random_bytes($pool_length)) === FALSE) - { - continue; - } - - $byte_index = 0; - break; + continue; } - if ($bytes === FALSE) - { - // Sadly, this means fallback to mt_rand() - $word = ''; - break; - } + $byte_index = 0; + break; + } + + if ($bytes === FALSE) + { + // Sadly, this means fallback to mt_rand() + $word = ''; + break; } + } + list(, $rand_index) = unpack('C', $bytes[$byte_index++]); + if ($rand_index > $rand_max) + { continue; } -- cgit v1.2.3-24-g4f1b From fd8d3987226bcde81db0682eee9c9acca0beb9a1 Mon Sep 17 00:00:00 2001 From: George Petculescu Date: Sun, 25 Sep 2016 19:52:58 +0300 Subject: - captcha helper uses now filemtime to get file timestamp - captcha generated files are a sha1 of current timestamp and word - changed the usage of microtime to time, as this is a more realistic approach Signed-off-by: George Petculescu --- system/helpers/captcha_helper.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 3c1e006f8..c2a1dcfbd 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -105,12 +105,13 @@ if ( ! function_exists('create_captcha')) // Remove old images // ----------------------------------- - $now = microtime(TRUE); + $now = time(); $current_dir = @opendir($img_path); while ($filename = @readdir($current_dir)) { - if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now) + if (in_array(substr($filename, -4), array('.jpg', '.png')) + && (filemtime($img_path.$filename) + $expiration) < $now) { @unlink($img_path.$filename); } @@ -319,12 +320,12 @@ if ( ! function_exists('create_captcha')) if (function_exists('imagejpeg')) { - $img_filename = $now.'.jpg'; + $img_filename = sha1($now.$word).'.jpg'; imagejpeg($im, $img_path.$img_filename); } elseif (function_exists('imagepng')) { - $img_filename = $now.'.png'; + $img_filename = sha1($now.$word).'.png'; imagepng($im, $img_path.$img_filename); } else -- cgit v1.2.3-24-g4f1b From 6ed047335d216a74162aab488002239235dfe95e Mon Sep 17 00:00:00 2001 From: George Petculescu Date: Tue, 27 Sep 2016 20:07:58 +0300 Subject: - revert --- system/helpers/captcha_helper.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index c2a1dcfbd..3c1e006f8 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -105,13 +105,12 @@ if ( ! function_exists('create_captcha')) // Remove old images // ----------------------------------- - $now = time(); + $now = microtime(TRUE); $current_dir = @opendir($img_path); while ($filename = @readdir($current_dir)) { - if (in_array(substr($filename, -4), array('.jpg', '.png')) - && (filemtime($img_path.$filename) + $expiration) < $now) + if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now) { @unlink($img_path.$filename); } @@ -320,12 +319,12 @@ if ( ! function_exists('create_captcha')) if (function_exists('imagejpeg')) { - $img_filename = sha1($now.$word).'.jpg'; + $img_filename = $now.'.jpg'; imagejpeg($im, $img_path.$img_filename); } elseif (function_exists('imagepng')) { - $img_filename = sha1($now.$word).'.png'; + $img_filename = $now.'.png'; imagepng($im, $img_path.$img_filename); } else -- cgit v1.2.3-24-g4f1b From 89eb04b5f09f4d7fb2d319e417bc188f0ed915d0 Mon Sep 17 00:00:00 2001 From: George Petculescu Date: Tue, 27 Sep 2016 20:25:43 +0300 Subject: - captcha helper will now look for .png files too when deleting old files --- system/helpers/captcha_helper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 3c1e006f8..f6c42b4f7 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -110,7 +110,8 @@ if ( ! function_exists('create_captcha')) $current_dir = @opendir($img_path); while ($filename = @readdir($current_dir)) { - if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now) + if (in_array(substr($filename, -4), array('.jpg', '.png')) + && (str_replace(array('.jpg', '.png'), '', $filename) + $expiration) < $now) { @unlink($img_path.$filename); } -- cgit v1.2.3-24-g4f1b From f394b9e0a764d47532363cae8f3e491718fcf8fa Mon Sep 17 00:00:00 2001 From: George Petculescu Date: Tue, 27 Sep 2016 20:28:24 +0300 Subject: - fixed identation --- system/helpers/captcha_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index f6c42b4f7..f2ff4dccf 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -111,7 +111,7 @@ if ( ! function_exists('create_captcha')) while ($filename = @readdir($current_dir)) { if (in_array(substr($filename, -4), array('.jpg', '.png')) - && (str_replace(array('.jpg', '.png'), '', $filename) + $expiration) < $now) + && (str_replace(array('.jpg', '.png'), '', $filename) + $expiration) < $now) { @unlink($img_path.$filename); } -- cgit v1.2.3-24-g4f1b From fced25f5728ce81fe810216fcaa4ccec7523f6c9 Mon Sep 17 00:00:00 2001 From: Master Yoda Date: Sat, 31 Dec 2016 08:46:18 -0800 Subject: Update copyright data to 2017 --- system/helpers/captcha_helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index f2ff4dccf..8f44806cc 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 1.0.0 -- cgit v1.2.3-24-g4f1b From cd78f072773bc670eb8ec13f2a3bff1d926d7b61 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 6 Jan 2017 12:50:58 +0200 Subject: [ci skip] A cosmetic change to the PR #4251 --- system/helpers/captcha_helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index 442a915ef..a79904c35 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -68,6 +68,7 @@ if ( ! function_exists('create_captcha')) 'img_url' => '', 'img_width' => '150', 'img_height' => '30', + 'img_alt' => 'captcha' 'font_path' => '', 'expiration' => 7200, 'word_length' => 8, @@ -79,8 +80,7 @@ if ( ! function_exists('create_captcha')) 'border' => array(153,102,102), 'text' => array(204,153,153), 'grid' => array(255,182,182) - ), - 'img_alt' => 'captcha' + ) ); foreach ($defaults as $key => $val) -- cgit v1.2.3-24-g4f1b From f41b4e33d1d5fe8d17b3d572b9676b0fdfedc8f7 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 16 Jan 2017 12:03:38 +0200 Subject: [ci skip] Fix #4985 --- system/helpers/captcha_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/helpers/captcha_helper.php') diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php index a79904c35..f98d8a4cd 100644 --- a/system/helpers/captcha_helper.php +++ b/system/helpers/captcha_helper.php @@ -68,7 +68,7 @@ if ( ! function_exists('create_captcha')) 'img_url' => '', 'img_width' => '150', 'img_height' => '30', - 'img_alt' => 'captcha' + 'img_alt' => 'captcha', 'font_path' => '', 'expiration' => 7200, 'word_length' => 8, -- cgit v1.2.3-24-g4f1b