Security advisory GHSA-6fqw-j3vm-7f66: Zendframework1 Potential SQL injection in ORDER and GROUP functions
Package: zendframework/zendframework1 (composer), vulnerable version: 1.12.19, fixed in: 1.12.20
CWE: CWE-89
Files changed by the fix:
b/library/Zend/Db/Select.php
b/library/Zend/Version.php

Fix diff:
diff -ruN --no-dereference /home/ubuntu/closed-source-intelligence/data/cache/composer-zips/zendframework-zendframework1-1.12.19/README.md /home/ubuntu/closed-source-intelligence/data/cache/composer-zips/zendframework-zendframework1-1.12.20/README.md
--- a/README.md
+++ b/README.md
@@ -18,17 +18,21 @@
 RELEASE INFORMATION
 ===================
 
-Zend Framework 1.12.19 Release.
-Released on July 13, 2016.
+Zend Framework 1.12.20 Release.
+Released on September 08, 2016.
 
-IMPORTANT FIXES FOR 1.12.19
+IMPORTANT FIXES FOR 1.12.20
 ---------------------------
 
-This release contains security fixes:
+**This release contains security updates:**
 
-- **ZF2016-02**: The implementation of `ORDER BY` and `GROUP BY` in
-  `Zend_Db_Select` contained potential SQL injection vulnerabilities,
-  and have been patched.
+- **ZF2016-03:** The implementation of `ORDER BY` and `GROUP BY` in
+  `Zend_Db_Select` remained prone to SQL injection when a combination of SQL
+  expressions and comments were used. This release provides a comprehensive
+  solution that identifies and removes comments prior to checking validity of
+  the statement to ensure no SQLi vectors occur. We advise always filtering user
+  input prior to invoking these methods, however, to further protect your
+  applications.
 
 See http://framework.zend.com/changelog for full details.
 
diff -ruN --no-dereference /home/ubuntu/closed-source-intelligence/data/cache/composer-zips/zendframework-zendframework1-1.12.19/library/Zend/Db/Select.php /home/ubuntu/closed-source-intelligence/data/cache/composer-zips/zendframework-zendframework1-1.12.20/library/Zend/Db/Select.php
--- a/library/Zend/Db/Select.php
+++ b/library/Zend/Db/Select.php
@@ -84,6 +84,23 @@
     const REGEX_COLUMN_EXPR       = '/^([\w]*\s*\(([^\(\)]|(?1))*\))$/';
     const REGEX_COLUMN_EXPR_ORDER = '/^([\w]+\s*\(([^\(\)]|(?1))*\))$/';
     const REGEX_COLUMN_EXPR_GROUP = '/^([\w]+\s*\(([^\(\)]|(?1))*\))$/';
+    
+    // @see http://stackoverflow.com/a/13823184/2028814
+    const REGEX_SQL_COMMENTS      = '@
+    (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions
+    |(                   # $3 : Match comments
+        (?:\#|--).*?$    # - Single line comments
+        |                # - Multi line (nested) comments
+         /\*             #   . comment open marker
+            (?: [^/*]    #   . non comment-marker characters
+                |/(?!\*) #   . ! not a comment open
+                |\*(?!/) #   . ! not a comment close
+                |(?R)    #   . recursive case
+            )*           #   . repeat eventually
+        \*\/             #   . comment close marker
+    )\s*                 # Trim after comments
+    |(?<=;)\s+           # Trim after semi-colon
+    @msx';
 
     /**
      * Bind variables for query
@@ -513,7 +530,9 @@
         }
 
         foreach ($spec as $val) {
-            if (preg_match(self::REGEX_COLUMN_EXPR_GROUP, (string) $val)) {
+            // Remove comments from SQL statement
+            $noComments = preg_replace(self::REGEX_SQL_COMMENTS, '$1', (string) $val);
+            if (preg_match(self::REGEX_COLUMN_EXPR_GROUP, $noComments)) {
                 $val = new Zend_Db_Expr($val);
             }
             $this->_parts[self::GROUP][] = $val;
@@ -605,7 +624,9 @@
                     $val = trim($matches[1]);
                     $direction = $matches[2];
                 }
-                if (preg_match(self::REGEX_COLUMN_EXPR_ORDER, (string) $val)) {
+                // Remove comments from SQL statement
+                $noComments = preg_replace(self::REGEX_SQL_COMMENTS, '$1', (string) $val);
+                if (preg_match(self::REGEX_COLUMN_EXPR_ORDER, $noComments)) {
                     $val = new Zend_Db_Expr($val);
                 }
                 $this->_parts[self::ORDER][] = array($val, $direction);
diff -ruN --no-dereference /home/ubuntu/closed-source-intelligence/data/cache/composer-zips/zendframework-zendframework1-1.12.19/library/Zend/Version.php /home/ubuntu/closed-source-intelligence/data/cache/composer-zips/zendframework-zendframework1-1.12.20/library/Zend/Version.php
--- a/library/Zend/Version.php
+++ b/library/Zend/Version.php
@@ -32,7 +32,7 @@
     /**
      * Zend Framework version identification - see compareVersion()
      */
-    const VERSION = '1.12.19';
+    const VERSION = '1.12.20';
 
     /**
      * The latest stable version Zend Framework available