跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何修复报表系统中的动态SQL注入漏洞_通过存储过程白名单控制执行权限

JeecgBoot积木报表queryFieldBySql接口因未授权且直接将用户输入的SQL交由FreeMarker解析,导致模板注入,进而触发RCE(CVE-2023-4450),影响JimuReport<1.6.1版本。 为什么报表系统里用存储过程也挡不住SQL注入 因为存储过程本身不免疫SQL注入——只要你在过程内部拼接用户输入,比如
EXEC(@sql)
或
sp_executesql @sql
且未校验参数内容,攻击者仍能通过
queryFieldBySql
这类接口注入恶意语句。JeecgBoot 积木报表就曾因此暴露出远程代码执行风险。 动态表名/字段排序必须用白名单,不能靠过滤字符 报表常需支持“按用户选的字段排序”或“查不同业务表”,此时
${sortField}
或
${tableName}
是高危点。正则过滤
union
、
sleep
等关键字容易被绕过(比如大小写变形、编码混淆、注释干扰),真正可靠的做法是: 预先定义合法值集合,如
["user_name", "create_time", "status"]
校验输入是否严格等于其中某一项,不匹配则拒绝请求 避免任何字符串拼接逻辑,连
INSTR()
或
LIKE
匹配都不要用 存储过程权限要收缩到最小,且禁止跨库调用 即使用了白名单,存储过程若以高权限账户(如
sa
、
root
)执行,仍可能被用于读取系统表、写文件甚至执行系统命令(如 MySQL 的
SELECT ... INTO OUTFILE
)。修复时必须: 防SQL注入的php类库 防SQL注入的php类库 下载 为报表专用创建独立数据库用户,仅授予
EXECUTE
权限在指定存储过程上 显式拒绝该用户对
information_schema
、
mysql
、
sys
等系统库的访问 存储过程内部禁用
OPENROWSET
(SQL Server)、
LOAD_FILE
(MySQL)等高危函数 MyBatis + 存储过程组合下最容易漏掉的坑 很多人以为“用了存储过程 +
#{}
就安全了”,但实际漏洞常出在调用层: