研读Tomcat源码来看URI处理特性

admin 2023年1月2日16:19:55评论29 views字数 2133阅读7分6秒阅读模式


前言

这里通过阅读源码和黑盒测试相结合的方式来更加透彻的了解Tomcat的url解析策略

parsePathParameters处理逻辑

Tomcat在处理每一次的请求的时候,主要的处理逻辑是在org.apache.coyote.http11.Http11Processor#service方法中进行对应的Processor层的服务

研读Tomcat源码来看URI处理特性

之后将会将请求转发到Adapter中去进行接下来的逻辑

这里主要是CoyoteAdapter#service方法中

研读Tomcat源码来看URI处理特性

进行请求的处理,而我们这篇文章中关注的有关于url解析的特点主要集中在该方法中调用了postParseRequest方法进行解析

研读Tomcat源码来看URI处理特性

跟进这个方法的调用,看看具体的逻辑是什么

研读Tomcat源码来看URI处理特性

这里将会判断req.scheme().isNull的返回值

如果不为空,也即是req.scheme返回的是https,则将会设置secure属性值为true

反之,如果为空,也即是http请求,将会将属性值设置为false

接下来的逻辑就是有代理就设置代理,没有的话,将会判断tomcat有没有对端口进行配置,如果这里是通过https进行请求,将会将服务端口设置为443,反之就是默认端口80

研读Tomcat源码来看URI处理特性

我这里的tomcat配置了端口为8080的,所以不会进入这个if语句

研读Tomcat源码来看URI处理特性

接下来就是从Request对象中获取到了请求的URI,首先判断这个URI是不是*

这里主要是用来检查ping OPTTIONS * request用的

研读Tomcat源码来看URI处理特性

再然后首先对URI进行进行了解码操作,之后再进入if语句之后,调用duplicate方法将原始的URI,也即是undecodedURI复制到解码后的URI中去

之后调用parsePathParameters方法进行path parameters的解析操作

研读Tomcat源码来看URI处理特性

首先是对复制过来的原始URI转化为字节数组之后,获取这个URI的ByteChunk对象

之后会判断在这个URI中是否有;这个分隔符,如果存在有这个分隔符,将会进入这个if语句进行后续的处理

研读Tomcat源码来看URI处理特性

前面主要是获取URI的开始下标,结束下标,pathParam的开始下标,pathParam的结束下标

这里主要看看pathParamEnd的获取方式

研读Tomcat源码来看URI处理特性

主要是遍历bytes参数中的每一个字节,筛选是否有b字节数组中的字节,这个数组也即是分隔符数组,包含有; /两个字符,如果没有找到,将会返回-1, 否则返回的是偏移地址

好了,现在回到parsePathParameters方法中的逻辑来

如果在第一个;后面出现了分隔符,将会进入if语句中去

研读Tomcat源码来看URI处理特性

这里面的逻辑主要是将第一个;出现之后的所有字符串全部传递给pv变量,并在之后调用setEnd设置结束位置

研读Tomcat源码来看URI处理特性

之后将会将pv中的字符串以等号作为分隔符,分别取取等号左边和右边的值,调用addPathParameter方法添加进入org.apache.coyote.Request类的pathParameters属性中去了

而如果这后面出现了分隔符,将会进入else语句中

研读Tomcat源码来看URI处理特性

也就是循环一次一次的获取pv值之后调用addPathParameter进行添加

这种的方式就有点像如果将sessionID保存在url中的形式

总结

这里可以简单做个总结

  • /upload;test  ==> /upload

  • /upload;test/ ==> /upload/

  • /upload;test;/ ==> /upload/

  • /upload;te;st/ ==> /upload/

  • /upload;te/st/ ==> /upload/st/

  • /upload;te/s;t/ ==> /upload/s/

  • /upload;te;s;t/ ==> /upload/

  • /upload;te;s/t/ ==> /upload/t/

这里通过黑白盒的方式,大概可以看出来,

  1. 在URI中以;开头,并且以;或者/结尾的地方将会在处理过程中进行舍弃

  2. 如果URI末尾存在/,解析之后的URI一定存在/

normalize处理逻辑

接下来我们回到postParseRequest方法中继续阅读Tomcat源码

在这里通过调用req.getURLDecoder().convert方法对URI进行url解码

研读Tomcat源码来看URI处理特性

这里主要是在URI的Byte数组中寻找是否存在有%, 之后进行后续解码操作

之后来到了normalize方法的调用

研读Tomcat源码来看URI处理特性

这一部分大概的逻辑就是如果URI开始的偏移地址也就是结束的偏移地址,将会返回400状态码,或者如果URI首个字符不是/的同时也不是\也会返回400状态码

之后会遍历URI中的所有字符,如果存在有ALLOW_BACKSLASH属性为true的时候将替换为/,如果存在有u0000字符,将直接返回400

研读Tomcat源码来看URI处理特性

之后,如果URI是以/./开头的,将会将其转化为/

如果是以/../开头的将会直接转化为/

研读Tomcat源码来看URI处理特性

简单测试一下

  • /upload/../ ==> /

  • /upload/./ ==> /upload/

  • /./upload/ ==> /upload/

  • /../upload/ ==> /upload/

  • upload/ ==> /upload/

  • \upload/ ==> /upload/


来源先知社区的【RoboTerh师傅

注:如有侵权请联系删除

研读Tomcat源码来看URI处理特性

 

如需进群进行技术交流,请扫该二维码

研读Tomcat源码来看URI处理特性

原文始发于微信公众号(衡阳信安):研读Tomcat源码来看URI处理特性

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年1月2日16:19:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   研读Tomcat源码来看URI处理特性http://cn-sec.com/archives/1494624.html

发表评论

匿名网友 填写信息