代码与表达式注入
这类问题指程序把外部输入当作代码或表达式求值:Python 的 eval 与 exec、JavaScript 的 eval 与 new Function、Java 的 ScriptEngine 与 SpEL、OGNL 表达式,本质相同。低代码平台、规则引擎、报表公式让用户自己写表达式,把风险推到业务人员也能触达的位置。判断标准始终是同一个:这个求值入口能否被外部输入影响。
基本信息
| 高风险能力 | Python 的 eval/exec/compile/pickle、JS 的 eval/new Function、Java 的 ScriptEngine/SpEL/OGNL |
|---|---|
| 高发场景 | 规则引擎、低代码公式、报表计算字段、动态路由与插件热加载 |
| 排查方式 | 对求值关键字做全量检索,逐处确认输入来源 |
| 替代方案 | AST 白名单解释器、JSON 或 DSL 固定引擎、映射表 |
| 加固要求 | 沙箱隔离、超时与内存限制、禁用网络与文件访问 |
| 留痕要求 | 记录谁在何时修改了表达式或规则 |
语言与风险点
| 语言 | 风险 API | 安全替代 |
|---|---|---|
| Python | eval、exec、compile、pickle | 用 ast.literal_eval 解析字面量,或 AST 白名单求值 |
| JavaScript | eval、new Function、字符串形式 setTimeout | JSON.parse 加显式函数调用 |
| Java | ScriptEngine、SpEL、OGNL | 固定规则引擎加白名单函数 |
| PHP | eval、字符串形式 assert、create_function | 映射表与匹配器,去掉动态求值 |
| 低代码平台 | 自定义公式与脚本字段、插件热加载 | 只提供受限公式语法与函数白名单 |
风险点排查清单
风险点排查清单
Python:eval / exec / compile / pickle
JavaScript:eval / new Function / setTimeout 字符串形式
Java:ScriptEngine、SpEL/OGNL 表达式
PHP:eval、assert 字符串形式、create_function
低代码平台:自定义公式与脚本字段、插件热加载
检索示例:grep -rn "eval(" --include=*.py . 逐处确认输入来源安全替代思路
安全替代思路
公式计算:用 AST 白名单解释器,仅允许算术、比较与白名单函数
规则配置:用 JSON/DSL 交给固定引擎执行,不做字符串代码拼接
数据转换:用模板参数或映射表,不把数据解析为代码
必须执行脚本时:独立沙箱进程 + 超时与内存限制 + 无网络无文件权限典型使用场景
- 代码审计中的注入点定位与输入来源追溯
- 新增规则引擎或公式功能时的设计评审
- 低代码平台上架前确认能力边界与函数白名单
- 渗透测试报告中代码注入类问题的整改举证
- 应急时定位可疑表达式的来源与修改记录
- 提交门禁中加入求值关键字的静态扫描
审计时对关键字做全量检索(如 grep -rn 'eval(' ),逐处确认输入来源;命中不等于漏洞,但每一处都需要能解释清楚。
把「沙箱执行用户脚本」当卖点但沙箱实现不严时,逃逸的后果等同于直接代码执行。这类能力上线前应单独做安全评审,并限制可调用的函数集合。