问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
浅谈JFinal请求解析过程
JFinal 是基于Java 语言的极速 web 开发框架,浅谈其中的请求解析过程。
0x00 前言 ======= JFinal 是基于 Java 语言的极速 WEB + ORM 框架。 JFinal在使用时会通过web.xml进行相应的配置,例如下面的例子: ```XML <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- jfinal配置 --> <filter> <filter-name>jfinal</filter-name> <filter-class>com.jfinal.core.JFinalFilter</filter-class> <init-param> <param-name>configClass</param-name> <param-value>com.jfinal.demo.Config</param-value> </init-param> </filter> <filter-mapping> <filter-name>jfinal</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> ``` 其中`configClass`参数的值`com.jfinal.demo.Config`是项目定义的`JFinalConfig`的实现类,其中会进行一些项目初始化的配置:  这里主要关注configRoute方法,例如如下的例子: 这里使用`Routes.add()`方法,向`Routes`添加了一个`Controller`。通过这种方式用来配置 JFinal 访问路由,如下代码配置了将”/test”映射到TestController,当访问/test时候将访问到TestController的index()方法,访问/test/info时候将访问到TestController的info()方法:  这里也可以通过使用JFinal的拓展组件,同样也可以像Spring一样去配置路由,原理也是一样的:  0x01 JFinal请求解析过程 ================= 大概知道JFinal的路由配置方法以后,看看其是怎么对请求进行解析的。 从上面的web.xml配置可以看到,其配置了一个过滤器`com.jfinal.core.JFinalFilter`,对应的作用范围是`/*`。也就是说这个Filter会拦截所有的请求。 JFinalFilter实现了javax.servlet.Filter接口,从这里也可以看出jFinal是基于Servlet实现的。JFinalFilter在项目初始化时对jFinal项目的配置(com.jfinal.core.Config)、路由表(Route)、映射表(ActionMapping)等进行配置,其中**路由解析是在JFinalFilter的dofilter方法完成的**。  1.1 过程分析 -------- 以jfinal3.6版本为例,查看JFinalFilter的dofilter方法的具体实现,首先获取request,response,设置编码,然后通过request.getRequestURI方法获取当前请求路径,如果contextPathLength不等于0的话,通过subString截取除主机名之后的action请求:  isHandled作为一个标记位,表示是否需要doFilter这个请求。然后通过handler链进行处理:  handler在初始化的时候被赋值,查看JFinalFilter的init方法,主要是在Jfinal.init进行初始化:  在JFinal.init方法调用了initHandler进行初始化:  可以看到实际对应的是ActionHandler。也就是说实际调用的是ActionHandler.handle(target, request, response, isHandled)方法:  继续跟进ActionHandler.handle(target, request, response, isHandled)方法,首先调用`target.indexOf('.')!=-1`进行判断,这里应该是为了过滤掉一些静态资源的请求,类似1.png、1.html等:  然后把isHandled标记改为true,表示要这个请求会被处理掉。然后调用actionMapping#getAction方法,根据用户的请求地址从actionMapping中获取相应的Action。 查看具体实现,根据用户的请求从map中获取Action(可以理解为是用于处理HTTP请求的)。这里是从mapping中获取的,mapping的初始化是在`com.jfinal.core.ActionMapping`的`buildActionMapping`方法,这里主要处理前面configRoute的配置,遍历`Routes`所有`Controller`、以及对应的`method`,然后进行相应的封装:  继续看获取Action处理的逻辑,如果没有获取到Action,那么截取到最后一个`/`之前的路径重新从map集合中获取Action,最后返回对应的Action:  拿到对应的Action后会继续找到对应的Controller以及相应的方法执行相应的逻辑:  0x02 潜在风险 ========= 以配合shiro进行鉴权为例: shiro.ini的配置如下,对于/admin/下的一级路由,需要认证后才能访问: ```Plain #路径角色权限设置 [urls] /login = anon /doLogin = anon /resources/** = anon /logout = logout /admin/* = authc ``` 正常情况下,未授权直接访问/admin/page会返回302跳转到登陆接口:  根据前面的分析,在没有获取到Action的前提下,JFinal会截取到最后一个`/`之前的路径重新从map集合中获取Action。也就是说/admin/page、/admin/page/、/admin/page/bypass请求到的Action是一致的。 对于结尾最后一个`/`的问题,shiro在之前已经有修复过了,所以/admin/page/是无法绕过的,但是JFinal在处理的时候比较粗糙,使用/admin/page/bypass即可绕过shiro的鉴权处理: 
发表于 2023-05-16 09:00:02
阅读 ( 6193 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
tkswifty
64 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!