CVE-2020-21665: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: In fastadmin V1.0.0.20191212_beta, when a user with administrator rights has logged in, a malicious parameter can be passed for SQL injection in URL /admin/ajax/weigh.
CWE 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.
CVSS v3 base score: 7.2
Published: 2020-11-17T15:15Z
Repository: https://github.com/karsonzhang/fastadmin
Language: PHP
Files changed: application/admin/controller/Ajax.php, application/common/controller/Backend.php, application/index/controller/User.php
Commit date: 2019-12-27 12:09:20 +0800
Commit message: 修复邮箱验证码错误
修复排序表名安全检测
修复Selectpage编辑时分页大小错误

Diff: diff --git a/application/admin/controller/Ajax.php b/application/admin/controller/Ajax.php
index 3ec4a12..5b9ac59 100644
--- a/application/admin/controller/Ajax.php
+++ b/application/admin/controller/Ajax.php
@@ -7,10 +7,11 @@ use fast\Random;
 use think\addons\Service;
 use think\Cache;
 use think\Config;
 use think\Db;
 use think\Lang;
+use think\Validate;
 
 /**
  * Ajax异步请求接口
  * @internal
  */
@@ -153,10 +154,13 @@ class Ajax extends Backend
         $changeid = $this->request->post("changeid");
         //操作字段
         $field = $this->request->post("field");
         //操作的数据表
         $table = $this->request->post("table");
+        if (!Validate::is($table, "alphaDash")) {
+            $this->error();
+        }
         //主键
         $pk = $this->request->post("pk");
         //排序的方式
         $orderway = strtolower($this->request->post("orderway", ""));
         $orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
@@ -212,20 +216,23 @@ class Ajax extends Backend
         switch ($type) {
             case 'all':
             case 'content':
                 rmdirs(CACHE_PATH, false);
                 Cache::clear();
-                if ($type == 'content')
+                if ($type == 'content') {
                     break;
+                }
             case 'template':
                 rmdirs(TEMP_PATH, false);
-                if ($type == 'template')
+                if ($type == 'template') {
                     break;
+                }
             case 'addons':
                 Service::refresh();
-                if ($type == 'addons')
+                if ($type == 'addons') {
                     break;
+                }
         }
 
         \think\Hook::listen("wipecache_after");
         $this->success();
     }
diff --git a/application/common/controller/Backend.php b/application/common/controller/Backend.php
index 8e3474b..896e0ae 100644
--- a/application/common/controller/Backend.php
+++ b/application/common/controller/Backend.php
@@ -449,10 +449,11 @@ class Backend extends Controller
         $field = $field ? $field : 'name';
 
         //如果有primaryvalue,说明当前是初始化传值
         if ($primaryvalue !== null) {
             $where = [$primarykey => ['in', $primaryvalue]];
+            $pagesize = null;
         } else {
             $where = function ($query) use ($word, $andor, $field, $searchfield, $custom) {
                 $logic = $andor == 'AND' ? '&' : '|';
                 $searchfield = is_array($searchfield) ? implode($logic, $searchfield) : $searchfield;
                 foreach ($word as $k => $v) {
diff --git a/application/index/controller/User.php b/application/index/controller/User.php
index 46bc2c6..2f1dc83 100644
--- a/application/index/controller/User.php
+++ b/application/index/controller/User.php
@@ -117,11 +117,11 @@ class User extends Frontend
             $captchaType = config("fastadmin.user_register_captcha");
             if ($captchaType) {
                 if ($captchaType == 'mobile') {
                     $captchaResult = Sms::check($mobile, $captcha, 'register');
                 } elseif ($captchaType == 'email') {
-                    $captchaResult = Ems::check($mobile, $captcha, 'register');
+                    $captchaResult = Ems::check($email, $captcha, 'register');
                 } elseif ($captchaType == 'wechat') {
                     $captchaResult = WechatCaptcha::check($captcha, 'register');
                 } elseif ($captchaType == 'text') {
                     $captchaResult = \think\Validate::is($captcha, 'captcha');
                 }

Vulnerable code:                 if ($type == 'content')
                if ($type == 'template')
                if ($type == 'addons')
                    $captchaResult = Ems::check($mobile, $captcha, 'register');
Fixed code: use think\Validate;
        if (!Validate::is($table, "alphaDash")) {
            $this->error();
        }
                if ($type == 'content') {
                }
                if ($type == 'template') {
                }
                if ($type == 'addons') {
                }
            $pagesize = null;
                    $captchaResult = Ems::check($email, $captcha, 'register');