低代码平台sql报表安全需三重控制:参数绑定、白名单校验与执行沙箱。必须禁用字符串拼接,仅允许#{param}占位符;动态条件用mybatis标签;表名字段名不可变量替换;禁止高危关键词;配置只读账号、超时、脱敏及完整审计日志。

不能直接执行用户输入的原始 SQL,必须经过参数绑定、白名单校验与执行沙箱三重控制——这是低代码平台中 SQL 报表安全落地的底线。
为什么 raw SQL 输入必须被拦截
用户在报表设计页手写 SELECT * FROM user_table WHERE name = 'xxx' 看似简单,但一旦支持字符串拼接,就等于开放了 SQL 注入入口。真实项目中,攻击者可能通过构造 ' OR 1=1 -- 绕过权限过滤,甚至拖库。
低代码平台(如 JeecgBoot、JimuReport)默认禁用自由文本 SQL 输入框,转而要求所有变量必须显式声明为输入参数,且仅允许在预设语法范围内使用。
- 动态条件只能通过
<if test="userId != null">AND user_id = #{userId}</if>这类 MyBatis 风格标签实现 - 表名、字段名等元数据不允许由变量替换,否则无法做语法预检
- 禁止出现
UNION SELECT、EXEC、xp_cmdshell等高危关键词,平台会在保存时实时扫描并报错SQL contains forbidden keywords
如何配置安全的 SQL 数据集(以 JimuReport 为例)
真正可上线的 SQL 数据集,不是“写完就跑”,而是要走完字段绑定、类型校验、权限注入三个环节。
- 在
SQL数据集编辑页填写的报表sql必须使用#{paramName}占位符,例如:SELECT id, name FROM student WHERE dept_id = #{deptId} - 点击
SQL解析后,系统会自动提取出deptId并生成对应输入字段,此时需手动设置其类型为Integer或String,防止类型绕过 - 若需行级权限,必须在 SQL 中显式引用内置变量,如
AND create_by = #{userId},平台会自动从当前登录上下文注入值,不依赖前端传参 - 勾选
是否分页后,平台将自动包裹LIMIT/OFFSET或ROWNUM,避免用户自己写分页逻辑导致全表扫描
执行阶段的隔离与降权策略
即使 SQL 语法合法、参数类型正确,执行环境仍需进一步收紧。生产环境绝不能用 DBA 账号连接数据库。
- 为报表模块单独配置只读数据库账号,权限仅限于
SELECT指定视图或表,禁用INSERT/UPDATE/DELETE/DROP - 设置单条 SQL 执行超时阈值(如
queryTimeout=10秒),防止慢查询拖垮整个报表服务 - 敏感字段(如身份证、手机号)必须在数据集层启用脱敏规则,例如将
id_card字段配置为mask:4,8,平台自动生成CONCAT(LEFT(id_card,4), '****', RIGHT(id_card,8)) - 所有 SQL 执行日志必须记录完整参数值(脱敏后)、执行耗时、调用者
userId和 IP,用于事后审计
最易被忽略的一点:SQL 数据集和图表部件解耦后,同一个数据集可能被多个看板复用。一旦某处修改了字段别名或计算逻辑,所有引用它的报表都会变更——这意味着权限控制和字段脱敏规则必须定义在数据集层,而不是图表层。否则,某个运营人员在看板里拖拽出一个未脱敏的字段,就等于绕过了全部防护。










