CVE-2018-18546 (published 2018-10-21T01:29Z)

ThinkPHP 3.2.4 has SQL Injection via the order parameter because the Library/Think/Db/Driver.class.php parseOrder function mishandles the key variable.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/top-think/thinkphp
commit_details: repo_url: https://github.com/top-think/thinkphp
author: thinkphp
author_date: 2018-10-08 21:54:51+08:00
msg: 改进
repository: repo_url: https://github.com/top-think/thinkphp
repo_name: top-think/thinkphp
description: ThinkPHP3.2 ——基于PHP5的简单快速的面向对象的PHP框架
repo_language: PHP
owner: top-think
file_changes: filename: Driver.class.php
change_type: ModificationType.MODIFY
diff: @@ -758,29 +758,29 @@ abstract class Driver
             return '';
         }
         $array = array();
+        if (is_string($order) && '[RAND]' != $order) {
+            $order = explode(',', $order);
+        }
+
         if (is_array($order)) {
             foreach ($order as $key => $val) {
                 if (is_numeric($key)) {
-                    if (false === strpos($val, '(') && false === strpos($val, ';')) {
-                        $array[] = $this->parseKey($val);
-                    }
-                } elseif (false === strpos($key, ')') && false === strpos($key, '#')) {
-                    $sort    = in_array(strtolower($val), array('asc', 'desc')) ? ' ' . $val : '';
+                    list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' ');
+                } else {
+                    $sort = $val;
+                }
+
+                if (preg_match('/^[\w]+$/', $key)) {
+                    $sort    = strtoupper($sort);
+                    $sort    = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : '';
                     $array[] = $this->parseKey($key, true) . $sort;
                 }
             }
         } elseif ('[RAND]' == $order) {
             // 随机排序
             $array[] = $this->parseRand();
-        } else {
-            foreach (explode(',', $order) as $val) {
-                if (preg_match('/\s+(ASC|DESC)$/i', rtrim($val), $match, PREG_OFFSET_CAPTURE)) {
-                    $array[] = $this->parseKey(ltrim(substr($val, 0, $match[0][1]))) . ' ' . $match[1][0];
-                } elseif (false === strpos($val, '(') && false === strpos($val, ';')) {
-                    $array[] = $this->parseKey($val);
-                }
-            }
         }
+
         $order = implode(',', $array);
         return !empty($order) ? ' ORDER BY ' . $order : '';
     }

programming_language: PHP