漏洞公告
漏洞分析
从公告中可知该漏洞关键点在 UriComponentsBuilder
这个类。通过以前的Springboot工程全局搜索可知该类在于spring-web 这个jar包里。于是我们可以diff 下 spring-web 的 5.3.31
和 5.3.32
这两个版本的jar。
可以看到,UriComponentsBuilder 类的改动只涉及三个正则表达式,虽然USERINFO_PATTERN
没有被引用,但从它的改动我们可以很清晰地差别,新版本的 USERINFO_PATTERN
去掉了左中括号[
。由此猜测,旧版本在解析url的时候,会由于[
符号的存在导致解析不正确。继续分析下 URI_PATTERN
,这个正则被 UriComponentsBuilder#fromUriString(String uri)
这个url解析方法使用到。
5.3.31 URI_PATTERN
^(([^:/?#]+):)?(//(([^@\[/?#]*)@)?(\[[\p{XDigit}:.]*[%\p{Alnum}]*]|[^\[/?#:]*)(:(\{[^}]+\}?|[^/?#]*))?)?([^?#]*)(\?([^#]*))?(#(.*))?5.3.32 URI_PATTERN
^(([^:/?#]+):)?(//(([^@/?#]*)@)?(\[[\p{XDigit}:.]*[%\p{Alnum}]*]|[^\[/?#:]*)(:(\{[^}]+\}?|[^/?#]*))?)?([^?#]*)(\?([^#]*))?(#(.*))?
由于该正则较复杂,看的头疼,于是直接扔给 GPT分析:
GPT给我的答案还是很准的,直击要害的。
意思就是,5.3.31版本中,url的userinfo部分(即 @
前面的部分),是不能包含 @
、[
、?
、#
符号的,如果@
出现了这几个符号,则@
前面的部分便不会认为是userInfo,因此也会导致 host部分(即@
后面的部分)解析出错。
以 url https://mole.sh[@evil.com
,按理正确的解析出userinfo部分应为:mole.sh[
,host的部分应为:evil.com
,但实际按照 5.3.31 版本的这个正则,解析出的host 却是 mole.sh
。
写个使用demo程序调试下:
@Testvoid testCVE_2024_22243() throws MalformedURLException {String url = "https://mole.sh[@evil.org";String normalizeUrl = UriComponentsBuilder.fromUriString(url).build().normalize().toString();System.out.println("normalizedUrl:" + normalizeUrl);System.out.println("url:" + url);URL tmpUrl = new URL(url);String host = tmpUrl.getHost();System.out.println("url host: " + host);URL norUrl = new URL(normalizeUrl);String host1 = norUrl.getHost();System.out.println("norUrl host: " + host1);}
调试结果对比如下,印证了我们的分析:
另外,从最后的运行输出结果可以看到,5.3.31 版本,经过 UriComponentsBuilder#fromUriString()
处理过后的url,在 mole.sh
后面加了个反斜杠/
,这样在 URL#getHost()
肯定得到的就是 mole.sh
。所以如果在发起请求前,使用了UriComponentsBuilder
对url进行解析并针对SSRF、Open Redirect进行安全校验,那么在构造URL对象后,得到的host就不会是evil.com
,从而绕过校验。
小结
虽然Spring官方对该漏洞的评级是High,但个人认为该漏洞还是比较鸡肋的,完全取决于产品开发是如何实现具体逻辑。而且现在很多产品都直接将url配在了配置中心。除非能修改配置中心,但如果能篡改配置,直接SpEL注入实现RCE不更香么...
查了下阿里云AVD的高危漏洞列表,果然榜上无名,评级为中危。