java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Eureka 漏洞修复

Spring Eureka 未授权访问漏洞修复问题小结

作者:JustDI-CM

项目组使用的 Spring Boot 比较老,是 1.5.4.RELEASE ,最近被检测出 Spring Eureka 未授权访问漏洞,这篇文章主要介绍了Spring Eureka 未授权访问漏洞修复问题小结,需要的朋友可以参考下

1. 背景

项目组使用的 Spring Boot 比较老,是 1.5.4.RELEASE 。最近被检测出 Spring Eureka 未授权访问漏洞。

现状是浏览器直接访问 Eureka Server 可以直接进去,看到已经注册的服务信息。

2. 方法

2.1 Eureka Server 添加安全组件

Eureka Server 添加 pom 依赖:

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

2.2 Eureka Server 添加参数

spring.application.name:demo-eureka
server.port: 8088
eureka.instance.hostname=localhost
#禁用将自己作为客户端注册,禁用客户端注册行为
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#eureka地址
eureka.client.service-url.defaultZone=http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka
#eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
#关闭自我保护 --本地开发环境可以关闭,生产环境
eureka.server.enable-self-preservation = false
#清理节点时间
eureka.server.eviction-interval-timer-in-ms = 60000
spring.security.basic.enabled=true
spring.security.user.name=demo
spring.security.user.password=123abcd

2.3 重启 Eureka Server

重启 Eureka Server ,然后刷新访问页面,显示登录框:

输入配置的用户名和密码。

spring.security.user.name=demo
spring.security.user.password=123abcd

然后就报错了:Reason: Bad credentials。

奇怪,明明是按照配置文件里面输入的,怎么还会报用户名或密码错误呢。

查了一些资料,说跟 security 加密方法有关,整了半天搞不定。

2.4 Eureka Server 升级版本

实在没招了,只能怀疑用的框架版本太低,去重新整一个,eureka 就用了个服务发现,问题不大。

访问:https://start.spring.io/

把项目下载到本地,依赖已经加好了:

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>

在启动类上加上注解:

package com.demo.cloudeurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class CloudEurekaServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(CloudEurekaServerApplication.class, args);
	}
}

再把 2.2 的参数加到 properties 文件中(最好换个 server.port),然后 run 启动类,访问 eureka ,输入用户名和密码,进去了:

2.5 Eureka Client 配置

eureka client 参数:

eureka.client.enabled=true
eureka.client.eureka-server-port=8089
eureka.client.service-url.defaultZone=http://demo:123abcd@localhost:8089/eureka/

启动 eureka client,报错:

javax.ws.rs.WebApplicationException: null
	at com.netflix.discovery.provider.DiscoveryJerseyProvider.readFrom(DiscoveryJerseyProvider.java:110)
	at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:634)
	at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:586)
	at com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient.sendHeartBeat(AbstractJerseyEurekaHttpClient.java:105)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92)
	at com.netflix.discovery.shared.transport.decorator.MetricsCollectingEurekaHttpClient.execute(MetricsCollectingEurekaHttpClient.java:73)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92)
	at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.executeOnNewServer(RedirectingEurekaHttpClient.java:118)
	at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.execute(RedirectingEurekaHttpClient.java:79)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92)
	at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:119)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92)
	at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89)
	at com.netflix.discovery.DiscoveryClient.renew(DiscoveryClient.java:824)
	at com.netflix.discovery.DiscoveryClient$HeartbeatThread.run(DiscoveryClient.java:1388)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
2023-11-03 14:41:26.339  WARN [test-app-service,,,] 16240 --- [tbeatExecutor-0] c.n.d.s.t.d.RetryableEurekaHttpClient    : Request execution failed with message: null
2023-11-03 14:41:26.339 ERROR [test-app-service,,,] 16240 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_TEST-APP-SERVICE/10.136.44.122:test-app-service:60000 - was unable to send heartbeat!
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
	at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:111)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92)
	at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77)
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89)
	at com.netflix.discovery.DiscoveryClient.renew(DiscoveryClient.java:824)
	at com.netflix.discovery.DiscoveryClient$HeartbeatThread.run(DiscoveryClient.java:1388)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

刷新 eureka 页面,也没有服务信息,服务注册失败了。

这是因为从 Spring Boot 2.0 开始,默认情况下会启用CSRF保护,以防止CSRF攻击应用程序,导致服务注册失败。

2.6 Eureka Server 添加代码

修改 Eureka Server :

package com.demo.cloudeurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableEurekaServer
@SpringBootApplication
public class CloudEurekaServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(CloudEurekaServerApplication.class, args);
	}
	/**
	 * springboot 从 2.0 开始,默认情况下会启用CSRF保护
	 * 需要关闭
	 */
	@EnableWebSecurity
	static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
		@Override
		protected void configure(HttpSecurity http) throws Exception {
			//方法1:关闭csrf
//			http.csrf().disable();
			//方法2:忽略/eureka/** 所有请求
			http.csrf().ignoringAntMatchers("/eureka/**");
			super.configure(http);
		}
	}
}

重启 Eureka Server 和 Eureka Client ,这次没有报错,刷新页面,重新登录后,看到注册的服务信息:

2.7 其他问题

在 Spring Security 5.7.0-M2 中,WebSecurityConfigurerAdapter 被弃用了,Spring 鼓励用户转向基于组件的安全配置。这意味着,现在应该使用基于组件的安全配置来配置 HttpSecurity,而不是继承 WebSecurityConfigurerAdapter。这种方式更加灵活,可以更好地支持 Spring Boot 2.x 和 Spring 5.x。

我试了几个方法,没有替换掉,靠你了,耿小姐。

到此这篇关于Spring Eureka 未授权访问漏洞修复问题小结的文章就介绍到这了,更多相关Spring Eureka 漏洞修复内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文