官方公众号企业安全新浪微博
FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。
FreeBuf+小程序
Preface
这里主要是对Java中的各种常见的表达式注入的各种类型和各种原理的一个较为全面的分析
EL(Expression-language)
brief
背景
EL是为了使
JSP
写起来更加简单, 它提供了在JSP
中简化表达式的方法, 让JSP
的代码更加简化
特点
可得到
PageContext
属性值.可直接访问
JSP
的内置对象, 如page
,request
,session
,application
等.运算符丰富, 有关系运算符、逻辑运算符、算术运算符等.
扩展函数可与
JAVA
类的静态方法对应.
简单使用
EL表达式的语法格式通过
${}
包裹在默认情况下,查找的范围为
page, request, session, application
域存取数据的两种方式:
.
and[]
,通常情况下两种方式都可以使用,但是有两种特殊情况如果属性名称包含有一些特殊字符,如
. -
等非字母和数字的,只能使用[xxx]
包裹属性如果需要动态取值,也只能通过
[]
获取属性
隐式对象
对象 解释 pageContext JSP页的上下文 param 获取请求参数,类似 request.getParameter()
paramValues 类似 request.getParameterValues()
header 获取请求头 headerValues 同paramValues cookie 获取cookie JSP中EL表达式的禁用
单个文件禁用
<%@page isELIgnored="true" %>
全局禁用
// web.xml <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <el-ignored>true</el-ignored> </jsp-property-group> </jsp-config>
detail
一个小例子
@RequestMapping("/el")
@ResponseBody
public String ElTest(@RequestParam(required = false) String expression) {
if (expression == null) {
return "Send request with \"expression\" parameter!";
}
try {
ExpressionFactoryImpl factory = new ExpressionFactoryImpl();
StandardELContext context = new StandardELContext(factory);
ValueExpression valueExpression = factory.createValueExpression(context, expression, String.class);
valueExpression.getValue(context);
} catch (Exception e) {
return Util.printStack(e);
}
return "OK!";
}
在通过ExpressionFactoryImpl#createValueExpression
方法根据expression
这个传入的表达式构造一个ValueExpression
对象
进而通过ExpressionBuilder#createValueExpression
方法来创建ValueExpression
对象
主要是通过build
方法来将表达式拆分成一个一个的结点
通过createNodeInternal
方法通过AST解析成一个一个的结点
在el.parser
包下的SimpleNode
这个抽象类的实现类中定义了很多有关EL表达式中的结点类型
类似于运算符结点,方法的参数结点等等
上面的内容主要是对${}
包裹的表达式进行解析成一个一个的结点,之后就是对内容进行执行,之后将执行的结果返回到页面中
也就是通过ValueExpressionImpl#getValue
方法来获取表达式执行后的值
核心是在this.getNode().getValue
方法的调用,这里是AstValue#getValue
方法
首先获取第一个子结点的值,并获取子结点的总个数
如果存在有次子结点,并且同时存在有次次结点且该结点为
AstMethodParameters
对象,之后获取该次次结点之后通过调用
resolver#invoke
方法结合base / suffix / params
进行计算