Pre Merge pull request !520 from 陈科宏/fix-selectpage-sqli

pull/520/MERGE
陈科宏 2026-03-22 06:45:23 +00:00 committed by Gitee
commit 0adcaefe63
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
1 changed files with 36 additions and 14 deletions

View File

@ -7,6 +7,7 @@ use think\Config;
use think\Controller; use think\Controller;
use think\Hook; use think\Hook;
use think\Lang; use think\Lang;
use think\Db;
use think\Loader; use think\Loader;
use think\Model; use think\Model;
use think\Session; use think\Session;
@ -494,6 +495,18 @@ class Backend extends Controller
$primarykey = $this->request->request("keyField"); $primarykey = $this->request->request("keyField");
//主键值 //主键值
$primaryvalue = $this->request->request("keyValue"); $primaryvalue = $this->request->request("keyValue");
// keyValue 与 keyField 必须成对合法,否则退回普通搜索,避免出现 [null => ...] 等异常条件
if ($primaryvalue === '') {
$primaryvalue = null;
}
$hasPrimaryInit = false;
if ($primaryvalue !== null) {
if (is_string($primarykey) && preg_match('/^[a-zA-Z0-9_\-]+$/i', $primarykey) === 1) {
$hasPrimaryInit = true;
} else {
$primaryvalue = null;
}
}
//搜索字段 //搜索字段
$searchfield = (array)$this->request->request("searchField/a"); $searchfield = (array)$this->request->request("searchField/a");
//自定义搜索条件 //自定义搜索条件
@ -511,8 +524,8 @@ class Backend extends Controller
} }
$field = $field ? $field : 'name'; $field = $field ? $field : 'name';
//如果有primaryvalue,说明当前是初始化传值 //如果有 primaryvalue 且 keyField 合法,说明当前是初始化传值
if ($primaryvalue !== null) { if ($hasPrimaryInit) {
$where = [$primarykey => ['in', $primaryvalue]]; $where = [$primarykey => ['in', $primaryvalue]];
$pagesize = 999999; $pagesize = 999999;
} else { } else {
@ -556,17 +569,26 @@ class Backend extends Controller
$fields = is_array($this->selectpageFields) ? $this->selectpageFields : ($this->selectpageFields && $this->selectpageFields != '*' ? explode(',', $this->selectpageFields) : []); $fields = is_array($this->selectpageFields) ? $this->selectpageFields : ($this->selectpageFields && $this->selectpageFields != '*' ? explode(',', $this->selectpageFields) : []);
//如果有primaryvalue,说明当前是初始化传值,按照选择顺序排序 // 初始化传值时按 FIELD 顺序排序(值使用 PDO 转义,防止注入)
if ($primaryvalue !== null && preg_match("/^[a-z0-9_\-]+$/i", $primarykey)) { if ($hasPrimaryInit && is_string($primarykey) && preg_match('/^[a-zA-Z0-9_\-]+$/i', $primarykey) === 1) {
$primaryvalue = array_unique(is_array($primaryvalue) ? $primaryvalue : explode(',', $primaryvalue)); $primaryValueList = is_array($primaryvalue) ? $primaryvalue : explode(',', (string)$primaryvalue);
//修复自定义data-primary-key为字符串内容时给排序字段添加上引号 $primaryValueList = array_values(array_unique(array_filter(
$primaryvalue = array_map(function ($value) { $primaryValueList,
return '\'' . $value . '\''; static function ($v) {
}, $primaryvalue); return $v !== null && $v !== '';
}
$primaryvalue = implode(',', $primaryvalue); )));
if ($primaryValueList !== []) {
$this->model->orderRaw("FIELD(`{$primarykey}`, {$primaryvalue})"); $pdo = Db::connect()->getPdo();
$quoted = [];
foreach ($primaryValueList as $value) {
$quoted[] = $pdo->quote((string)$value);
}
$columnExpr = '`' . str_replace('.', '`.`', $primarykey) . '`';
$this->model->orderRaw('FIELD(' . $columnExpr . ', ' . implode(',', $quoted) . ')');
} else {
$this->model->order($order);
}
} else { } else {
$this->model->order($order); $this->model->order($order);
} }
@ -592,7 +614,7 @@ class Backend extends Controller
}, $result); }, $result);
$list[] = $result; $list[] = $result;
} }
if ($istree && !$primaryvalue) { if ($istree && !$hasPrimaryInit) {
$tree = Tree::instance(); $tree = Tree::instance();
$tree->init(collection($list)->toArray(), 'pid'); $tree->init(collection($list)->toArray(), 'pid');
$list = $tree->getTreeList($tree->getTreeArray(0), $field); $list = $tree->getTreeList($tree->getTreeArray(0), $field);