From d28147b2ab41e03c6e573c9ec0138ecaaf09a5c3 Mon Sep 17 00:00:00 2001 From: lobo Date: Thu, 24 Sep 2026 10:26:53 +0200 Subject: [PATCH] fix(security): hide health details and close Prometheus to the public /actuator/health showed database and disk details to anyone, and /actuator/prometheus was open. Only health stays public, as plain UP/DOWN for the Docker health check. --- .../security/SecurityConfig.java | 3 +- src/main/resources/application.yml | 9 ++--- .../security/PublicEndpointsTest.java | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 src/test/java/auth_service/configuration/security/PublicEndpointsTest.java diff --git a/src/main/java/auth_service/configuration/security/SecurityConfig.java b/src/main/java/auth_service/configuration/security/SecurityConfig.java index 7829f00..b7f92df 100644 --- a/src/main/java/auth_service/configuration/security/SecurityConfig.java +++ b/src/main/java/auth_service/configuration/security/SecurityConfig.java @@ -36,8 +36,7 @@ public class SecurityConfig { "/api/auth/**", // Allow login, registration, etc. "/api/registration/**", // Allow new user registration "/api/stats/public", // Public landing-page counters (cached, no PII) - "/actuator/health", // Allow health checks (e.g., for Docker/Traefik) - "/actuator/prometheus", // Allow Prometheus to scrape metrics + "/actuator/health", // Docker health check; details are off "/error" // Default Spring Boot error page routing }; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c62e9a5..fc78f64 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -31,15 +31,10 @@ management: endpoints: web: exposure: - # Expose health and metrics to the web - include: health, prometheus, metrics + include: health endpoint: health: - show-details: always - prometheus: - metrics: - export: - enabled: true + show-details: never # Security stuff security: diff --git a/src/test/java/auth_service/configuration/security/PublicEndpointsTest.java b/src/test/java/auth_service/configuration/security/PublicEndpointsTest.java new file mode 100644 index 0000000..1f62f69 --- /dev/null +++ b/src/test/java/auth_service/configuration/security/PublicEndpointsTest.java @@ -0,0 +1,35 @@ +package auth_service.configuration.security; + +import auth_service.shared.test.AbstractIntegrationTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +class PublicEndpointsTest extends AbstractIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void healthIsPublicWithoutDetails() throws Exception { + mockMvc.perform(get("/actuator/health")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.status").value("UP")) + .andExpect(jsonPath("$.components").doesNotExist()); + } + + @Test + void prometheusIsNotPublic() throws Exception { + int status = mockMvc.perform(get("/actuator/prometheus")).andReturn().getResponse().getStatus(); + assertTrue(Set.of(401, 403).contains(status), "/actuator/prometheus answered " + status); + } +}