Java Configuration 47-Spring Eureka Unauthorized Access Vulnerability Fix

Article directory

    • 1. Background
    • 2. Method
      • 2.1 Eureka Server adds security components
      • 2.2 Eureka Server adding parameters
      • 2.3 Restart Eureka Server
      • 2.4 Eureka Server upgraded version
      • 2.5 Eureka Client configuration
      • 2.6 Eureka Server Add Code
      • 2.7 Other issues

1. Background

The Spring Boot used by the project team is relatively old, 1.5.4.RELEASE. An unauthorized access vulnerability in Spring Eureka was recently detected.

The current situation is that the browser can access Eureka Server directly and see the registered service information.

2. Method

2.1 Eureka Server adds security components

Eureka Server adds pom dependency:

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

2.2 Eureka Server adding parameters

spring.application.name:demo-eureka
server.port: 8088
eureka.instance.hostname=localhost
#Disable registering yourself as a client and disable client registration behavior
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#eurekaaddress
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
#Close self-protection --The local development environment can be closed, and the production environment
eureka.server.enable-self-preservation = false
#Clean node time
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 Restart Eureka Server

Restart Eureka Server, then refresh the access page to display the login box:

Enter the configured username and password.

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

Then an error was reported: Reason: Bad credentials.

It’s strange. It’s obviously entered according to the configuration file, but it still reports that the user name or password is wrong.

After checking some information, it was said that it was related to the security encryption method, but I couldn’t figure it out for a long time.

2.4 Eureka Server upgraded version

There is really no other way to do it. I can only suspect that the framework version used is too low and reinstall it. Eureka uses service discovery and the problem is not big.

Visit: https://start.spring.io/

Download the project locally and the dependencies have been added:

 <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>

Add annotations to the startup class:

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);
}

}

Then add the parameters of 2.2 to the properties file (it is best to change server.port), then run to start the class, access eureka, enter the user name and password, and enter:

2.5 Eureka Client Configuration

eureka client parameters:

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

Start eureka client and report error:

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)

Refresh the eureka page, there is no service information, and the service registration failed.

This is because starting from Spring Boot 2.0, CSRF protection is enabled by default to prevent CSRF from attacking the application and causing service registration to fail.

2.6 Eureka Server Add Code

Modify 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);
}

/**
* Starting from springboot 2.0, CSRF protection is enabled by default
* Need to close
*/
@EnableWebSecurity
static class WebSecurityConfig extends WebSecurityConfigurerAdapter {<!-- -->
@Override
protected void configure(HttpSecurity http) throws Exception {<!-- -->
//Method 1: Close csrf
// http.csrf().disable();
//Method 2: Ignore all requests for /eureka/**
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
}

Restart Eureka Server and Eureka Client. No error is reported this time. Refresh the page. After logging in again, you will see the registered service information:

2.7 Other issues

In Spring Security 5.7.0-M2, the WebSecurityConfigurerAdapter is deprecated and Spring encourages users to move to component-based security configuration. This means that HttpSecurity should now be configured using component-based security configuration instead of inheriting from WebSecurityConfigurerAdapter. This approach is more flexible and can better support Spring Boot 2.x and Spring 5.x.

I tried several methods but couldn’t replace it. It’s up to you, Miss Geng.

Let’s do this first.

(Picture network, intrusion and deletion)