Vulnerability: simple-php-captcha before commit 9d65a945029c7be7bb6bc893759e74c5636be694 allows remote attackers to automatically generate the captcha response by running the same code on the client-side.
Vulnerability ID: CVE-2015-6250
CWE: CWE-200
Severity score: 2.9
Project: https://github.com/claviska/simple-php-captcha
Published: 2017-09-06
File: simple-php-captcha.php
Commit message: Merge pull request #17 from ALSchwalm/master

Switch from rand to mt_rand
Commit author: Cory LaViska

Vulnerable version (before fix):
 function simple_php_captcha($config = array()) {     // Generate CAPTCHA code if not set by user     if( empty($captcha_config['code']) ) {         $captcha_config['code'] = '';         $length = rand($captcha_config['min_length'], $captcha_config['max_length']);         while( strlen($captcha_config['code']) < $length ) {             $captcha_config['code'] .= substr($captcha_config['characters'], rand() % (strlen($captcha_config['characters'])), 1);         }     }  function hex2rgb($hex_str, $return_string = false, $separator = ',') {     unset($_SESSION['_CAPTCHA']);      // Pick random background, get info, and start captcha     $background = $captcha_config['backgrounds'][rand(0, count($captcha_config['backgrounds']) -1)];     list($bg_width, $bg_height, $bg_type, $bg_attr) = getimagesize($background);      $captcha = imagecreatefrompng($background); function hex2rgb($hex_str, $return_string = false, $separator = ',') {     $color = imagecolorallocate($captcha, $color['r'], $color['g'], $color['b']);      // Determine text angle     $angle = rand( $captcha_config['angle_min'], $captcha_config['angle_max'] ) * (rand(0, 1) == 1 ? -1 : 1);      // Select font randomly     $font = $captcha_config['fonts'][rand(0, count($captcha_config['fonts']) - 1)];      // Verify font file exists     if( !file_exists($font) ) throw new Exception('Font file not found: ' . $font);      //Set the font size.     $font_size = rand($captcha_config['min_font_size'], $captcha_config['max_font_size']);     $text_box_size = imagettfbbox($font_size, $angle, $font, $captcha_config['code']);      // Determine text position     $box_width = abs($text_box_size[6] - $text_box_size[2]);     $box_height = abs($text_box_size[5] - $text_box_size[1]);     $text_pos_x_min = 0;     $text_pos_x_max = ($bg_width) - ($box_width);     $text_pos_x = rand($text_pos_x_min, $text_pos_x_max);     $text_pos_y_min = $box_height;     $text_pos_y_max = ($bg_height) - ($box_height / 2);     $text_pos_y = rand($text_pos_y_min, $text_pos_y_max);      // Draw shadow     if( $captcha_config['shadow'] ){

Fixed version (after fix):
 function simple_php_captcha($config = array()) {     // Generate CAPTCHA code if not set by user     if( empty($captcha_config['code']) ) {         $captcha_config['code'] = '';         $length = mt_rand($captcha_config['min_length'], $captcha_config['max_length']);         while( strlen($captcha_config['code']) < $length ) {             $captcha_config['code'] .= substr($captcha_config['characters'], mt_rand() % (strlen($captcha_config['characters'])), 1);         }     }  function hex2rgb($hex_str, $return_string = false, $separator = ',') {     unset($_SESSION['_CAPTCHA']);      // Pick random background, get info, and start captcha     $background = $captcha_config['backgrounds'][mt_rand(0, count($captcha_config['backgrounds']) -1)];     list($bg_width, $bg_height, $bg_type, $bg_attr) = getimagesize($background);      $captcha = imagecreatefrompng($background); function hex2rgb($hex_str, $return_string = false, $separator = ',') {     $color = imagecolorallocate($captcha, $color['r'], $color['g'], $color['b']);      // Determine text angle     $angle = mt_rand( $captcha_config['angle_min'], $captcha_config['angle_max'] ) * (mt_rand(0, 1) == 1 ? -1 : 1);      // Select font randomly     $font = $captcha_config['fonts'][mt_rand(0, count($captcha_config['fonts']) - 1)];      // Verify font file exists     if( !file_exists($font) ) throw new Exception('Font file not found: ' . $font);      //Set the font size.     $font_size = mt_rand($captcha_config['min_font_size'], $captcha_config['max_font_size']);     $text_box_size = imagettfbbox($font_size, $angle, $font, $captcha_config['code']);      // Determine text position     $box_width = abs($text_box_size[6] - $text_box_size[2]);     $box_height = abs($text_box_size[5] - $text_box_size[1]);     $text_pos_x_min = 0;     $text_pos_x_max = ($bg_width) - ($box_width);     $text_pos_x = mt_rand($text_pos_x_min, $text_pos_x_max);     $text_pos_y_min = $box_height;     $text_pos_y_max = ($bg_height) - ($box_height / 2);     if ($text_pos_y_min > $text_pos_y_max) {         $temp_text_pos_y = $text_pos_y_min;         $text_pos_y_min = $text_pos_y_max;         $text_pos_y_max = $temp_text_pos_y;     }     $text_pos_y = mt_rand($text_pos_y_min, $text_pos_y_max);      // Draw shadow     if( $captcha_config['shadow'] ){

Patch:
patch: @@ -62,9 +62,9 @@ function simple_php_captcha($config = array()) {
     // Generate CAPTCHA code if not set by user
     if( empty($captcha_config['code']) ) {
         $captcha_config['code'] = '';
-        $length = rand($captcha_config['min_length'], $captcha_config['max_length']);
+        $length = mt_rand($captcha_config['min_length'], $captcha_config['max_length']);
         while( strlen($captcha_config['code']) < $length ) {
-            $captcha_config['code'] .= substr($captcha_config['characters'], rand() % (strlen($captcha_config['characters'])), 1);
+            $captcha_config['code'] .= substr($captcha_config['characters'], mt_rand() % (strlen($captcha_config['characters'])), 1);
         }
     }
 
@@ -119,7 +119,7 @@ function hex2rgb($hex_str, $return_string = false, $separator = ',') {
     unset($_SESSION['_CAPTCHA']);
 
     // Pick random background, get info, and start captcha
-    $background = $captcha_config['backgrounds'][rand(0, count($captcha_config['backgrounds']) -1)];
+    $background = $captcha_config['backgrounds'][mt_rand(0, count($captcha_config['backgrounds']) -1)];
     list($bg_width, $bg_height, $bg_type, $bg_attr) = getimagesize($background);
 
     $captcha = imagecreatefrompng($background);
@@ -128,27 +128,32 @@ function hex2rgb($hex_str, $return_string = false, $separator = ',') {
     $color = imagecolorallocate($captcha, $color['r'], $color['g'], $color['b']);
 
     // Determine text angle
-    $angle = rand( $captcha_config['angle_min'], $captcha_config['angle_max'] ) * (rand(0, 1) == 1 ? -1 : 1);
+    $angle = mt_rand( $captcha_config['angle_min'], $captcha_config['angle_max'] ) * (mt_rand(0, 1) == 1 ? -1 : 1);
 
     // Select font randomly
-    $font = $captcha_config['fonts'][rand(0, count($captcha_config['fonts']) - 1)];
+    $font = $captcha_config['fonts'][mt_rand(0, count($captcha_config['fonts']) - 1)];
 
     // Verify font file exists
     if( !file_exists($font) ) throw new Exception('Font file not found: ' . $font);
 
     //Set the font size.
-    $font_size = rand($captcha_config['min_font_size'], $captcha_config['max_font_size']);
+    $font_size = mt_rand($captcha_config['min_font_size'], $captcha_config['max_font_size']);
     $text_box_size = imagettfbbox($font_size, $angle, $font, $captcha_config['code']);
 
     // Determine text position
     $box_width = abs($text_box_size[6] - $text_box_size[2]);
     $box_height = abs($text_box_size[5] - $text_box_size[1]);
     $text_pos_x_min = 0;
     $text_pos_x_max = ($bg_width) - ($box_width);
-    $text_pos_x = rand($text_pos_x_min, $text_pos_x_max);
+    $text_pos_x = mt_rand($text_pos_x_min, $text_pos_x_max);
     $text_pos_y_min = $box_height;
     $text_pos_y_max = ($bg_height) - ($box_height / 2);
-    $text_pos_y = rand($text_pos_y_min, $text_pos_y_max);
+    if ($text_pos_y_min > $text_pos_y_max) {
+        $temp_text_pos_y = $text_pos_y_min;
+        $text_pos_y_min = $text_pos_y_max;
+        $text_pos_y_max = $temp_text_pos_y;
+    }
+    $text_pos_y = mt_rand($text_pos_y_min, $text_pos_y_max);
 
     // Draw shadow
     if( $captcha_config['shadow'] ){
path: simple-php-captcha.php