Skip to content

Latest commit

 

History

History
95 lines (78 loc) · 2.68 KB

File metadata and controls

95 lines (78 loc) · 2.68 KB

Java 表达式注入

一句话理解

Java 表达式注入是一个总称,指用户输入进入 OGNL、SpEL、JEXL、MVEL、AviatorScript、Groovy 等表达式或脚本引擎后,被当成可执行表达式解释,从而访问对象、调用方法,甚至实现远程代码执行。

常见类型

  • SpEL
  • OGNL
  • JEXL
  • MVEL
  • AviatorScript
  • Groovy 表达式 / 脚本

与命令执行的关系

表达式注入不一定一开始就能直接执行系统命令,但它通常是通往 RCE 的前置入口。
只要表达式能力足够强,或者上下文对象暴露过多,攻击者就可能:

  • 访问应用对象
  • 调用类和方法
  • 执行脚本
  • 触发命令执行

常见成因

  • 把用户输入直接传给表达式引擎
  • 在规则引擎、权限判断、模板渲染、动态计算中使用可控表达式
  • 后台支持“自定义规则”“自定义公式”“自定义模板”
  • 误以为只允许数学表达式,但实际暴露了完整对象上下文

常见危害

  • 读取配置和运行时对象
  • 访问 Bean、Context、Request、Session
  • 调用危险类方法
  • 命令执行
  • 作为进入框架内部对象图的跳板

实战排查思路

1. 先识别具体引擎

不同引擎语法不同,利用方式差异很大。
排查重点:

  • 依赖包
  • 报错信息
  • 方法名
  • 模板和表达式语法特征

2. 再看输入控制点

关键在于:

  • 用户能否控制表达式本身
  • 用户能否影响表达式上下文

3. 再看可达对象

如果能访问:

  • Request
  • Session
  • Spring Context
  • BeanFactory
  • ClassLoader

风险会明显提高。

高危场景

  • 规则引擎
  • 流程引擎
  • 权限表达式
  • 搜索过滤器
  • 报表公式
  • 低代码平台
  • 模板预览和自定义页面

常见绕过思路

  • 关键字黑名单绕过
  • 字符串拼接绕过
  • 借助上下文对象间接访问危险类
  • 利用引擎特有语法规避过滤

防御要点

1. 不执行不可信表达式

这是根本原则。

2. 只开放安全子集

若业务必须支持表达式,应限制为固定字段、固定运算、固定函数。

3. 限制上下文对象

不要把应用运行时对象直接暴露给表达式环境。

4. 不依赖黑名单

表达式注入绕过空间通常很大,黑名单容易失效。

速查清单

  • 先识别具体引擎,不要把所有表达式问题混在一起
  • 先找表达式入口,再看上下文对象
  • 看是否能访问类、方法、Bean、运行时对象
  • 高优先排查规则引擎、低代码平台、后台动态配置功能
  • 一旦可控表达式成立,就继续判断能否升级为 RCE

Reference