freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

简单看下最近的Spring Secrurity、Spring漏洞
2024-03-01 11:26:26

最近的这两个cve我看国内很多情报将其评为高危,所以想着去看看原理,看完发现都比较简单,利用要求的场景也相对有限(特别是第一个),所以就随便看下就行了

Spring Security 用户认证绕过(CVE-2024-22234)

先看下官网的公告(https://spring.io/security/cve-2024-22234)

In Spring Security, versions 6.1.x prior to 6.1.7 and versions 6.2.x prior to 6.2.2, an application is vulnerable to broken access control when it directly uses theAuthenticationTrustResolver.isFullyAuthenticated(Authentication)method.

Specifically, an application is vulnerable if:

  • The application usesAuthenticationTrustResolver.isFullyAuthenticated(Authentication)directly and anullauthentication parameter is passed to it resulting in an erroneoustruereturn value.

An application is not vulnerable if any of the following is true:

  • The application does not useAuthenticationTrustResolver.isFullyAuthenticated(Authentication)directly.

  • The application does not passnulltoAuthenticationTrustResolver.isFullyAuthenticated

  • The application only usesisFullyAuthenticatedvia Method Securityor HTTP Request Security

大概意思是直接调用``AuthenticationTrustResolver.isFullyAuthenticated(Authentication)` ,若Authentication为null,则方法会永远返回真,从而产生一些与预期相反的结果。

AuthenticationTrustResolver接口中的isFullyAuthenticated方法用于检查Authentication对象是否完全经过身份验证,即是否不是匿名用户。在 Spring Security 中,可以使用这个方法来确定用户是否已经进行了完整的身份验证。

影响版本为:

  • 6.1.0 to 6.1.6

  • 6.2.0 to 6.2.1

环境搭建

引入pom,实际调用:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

增加下密码验证和/index的无鉴权的配置(交给应用手动配置)

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests((requests) -> requests
                        .requestMatchers("/", "/index").permitAll()  // 端点/、/index 无需鉴权,交给应用直接控制
                        .anyRequest().authenticated()
                )
                .formLogin((form) -> form
                        .loginPage("/login")
                        .permitAll()
                )
                .logout((logout) -> logout.permitAll());

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user =
                User.withDefaultPasswordEncoder()
                        .username("user")
                        .password("password")
                        .roles("USER")
                        .build();

        return new InMemoryUserDetailsManager(user);
    }
}

新增控制器并配置需要用户手动输入密码(isFullyAuthenticated)后才能访问的逻辑:

@GetMapping("/index")
    @ResponseBody
    public String index(){

        // CVE-2024-22234

        // 获取当前的认证对象
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        System.out.println(authentication);

        // 创建 AuthenticationTrustResolver 实例
        AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();

        // 使用 isFullyAuthenticated 方法检查是否完全经过身份验证
        boolean fullyAuthenticated = trustResolver.isFullyAuthenticated(authentication);  // 传递null返回即为true
        String msg = "";
        if (fullyAuthenticated) {
            msg = "用户已完全经过身份验证";
        } else {
            msg = "用户可能是匿名用户或者仅部分经过身份验证";
        }
        return msg;
    }

复现

正常情况下,如果没有经过认证,返回的页面为:

image-20240227112713342

进入登录页面正常登录后

image-20240227113132942

返回的页面为:

image-20240227113142148

如果开发在某些情况,比如手动清除SecurityContextHolder中的Authentication信息或通过异步处理导致在异步线程中没有可用的信息getAuthentication()返回null, 则会导致认证校验的失效,我们这里为了复现就手动置为null,

boolean fullyAuthenticated = trustResolver.isFullyAuthenticated(null);

重启应用,在不登陆的情况下,重新访问/index,发现isFullyAuthenticated已经直接返回了true 。访问鉴权后的页面

image-20240227115847155

修复

修复方式也比较简单在isFullyAuthenticated中增加了对authentication对象为空的判断

image-20240223151856512

Spring Framework SSRF or open redirect( CVE-2024-22243)

Applications that useUriComponentsBuilderto parse an externally provided URL (e.g. through a query parameter) ANDperform validation checks on the host of the parsed URL may be vulnerable to a open redirectattack or to a SSRF attack if the URL is used after passing validation checks.

这个看官网描述只知道使用UriComponentsBuilder这个方法来做host校验,会导致重定向和ssrf,粗看下源码不知道是怎么回事,看了下代码更新记录,很简单只是将uri匹配中userinfo匹配的正则表达式去掉[

image-20240223175826813

pre:

private static final String USERINFO_PATTERN = "([^@\\[/?#]*)";

now:

private static final String USERINFO_PATTERN = "([^@/?#]*)";

环境搭建

这里假设存在一个场景,后端会将用户输入的url交给UriComponentsBuilder进行验证,通过后进行正常的访问,后端有个简单的黑名单host判断(evil.com) :

String url = "http://xxx.com";
UriComponents uriComponents = UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build();
String host = uriComponents.getHost();
System.out.println("userinfo: " + uriComponents.getUserInfo());
System.out.println("host: " + host);
// 如果host为 evil.com 则会被拦截
if (host != null && host.equals("evil.com")) {
    System.out.println("403");

}else {
    System.out.println("pass");
}

简单场景,排除使用302、ip、rebind等方式,单纯从UriComponentsBuilder来进行绕过有什么办法?

复现

一般情况下我们知道绕过ssrf会用到@,如果url为http://A.com@B.com ,部分的host校验库会识别这个urlHost为A.com,而浏览器或者http client实际会访问B.com 利用这种差异就能绕过部分黑名单限制,直接访问恶意网站。

试下UriComponentsBuilder 可不可以:

很明显,在这个方法中,直接这么用是不行的,但根据漏洞的修复删除的正则表达式符号来看,我们在userinfo最后增加一个[,测试一下

成功绕过:

不过这样绕过后大部分情况下不能直接使用原url进行访问,因为url中存在[会让程序报错:

所以更多利用场景我猜可能是使用UriComponentsBuilder取的host重新进行url拼接来进行访问

总结

Spring Security中这个漏洞可能对于实战利用不大,因为黑盒测未授权都能测试出来不需要什么用户可控的绕过姿势,相对而言Spring Framework这个在实战中对于url可控的地方增加xxx[@yyy.com可能会有奇效。

# web安全 # Spring漏洞 # Spring # Java代码审计 # JAVA安全
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录