skip to content

How would you safely expose these diagnostic endpoints in production, given heapdump/threaddump can leak sensitive data?

level: principalimportance: should knowfreq 35%

answer

  1. only health public; never exposure.include=* in prod
  2. separate management.server.port + address (internal)
  3. Spring Security EndpointRequest.toAnyEndpoint() + role
  4. heapdump = secret exfil; capture from replica / OOM flag
  5. management.endpoint.heapdump.access=none until needed

basics

~10 s

Don't expose them publicly. Keep only health public, put diagnostic endpoints behind authentication/authorization, ideally on a separate internal management port, and restrict access to operators. Treat any heap dump as a secret.

solid answer

~50 s

Because heapdump externalizes raw memory (secrets, tokens, PII) and threaddump reveals internals, I treat these as privileged operator tools, not public endpoints. In production I: keep only /actuator/health (and maybe info) web-exposed for load balancers; move management to a separate port via management.server.port bound to an internal interface / management.server.address so the actuator isn't reachable from the public listener; secure all actuator routes with Spring Security using EndpointRequest.toAnyEndpoint() requiring an operator role; and never add sensitive headers to httpexchanges recording. I gate the network too — actuator port reachable only from the ops network / mesh, not the internet. For heap dumps specifically I prefer capturing from a drained replica or via -XX:+HeapDumpOnOutOfMemoryError rather than pulling live under load, and I handle any downloaded .hprof as a secret artifact (encrypted at rest, deleted after analysis). I also consider disabling heapdump entirely (management.endpoint.heapdump.access=none) unless needed.

code

java · 18 lines
java
import static org.springframework.security.config.Customizer.withDefaults;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Bean
SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
    http.securityMatcher(EndpointRequest.toAnyEndpoint())
        .authorizeHttpRequests(auth -> auth
            // health/liveness/readiness open for probes
            .requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll()
            // everything else (threaddump, heapdump, httpexchanges) requires operator role
            .anyRequest().hasRole("ACTUATOR"))
        .httpBasic(withDefaults());
    return http.build();
}

go deeper

for a junior

Know these endpoints are sensitive and shouldn't be public.

for a middle

Restrict exposure to health and secure the rest with Spring Security.

for a senior

Use a separate management port + EndpointRequest-based authorization and per-endpoint access control.

for a principal

Design the full defense-in-depth posture (network isolation, auth, per-endpoint access, heap-dump lifecycle/DoS, auditing) and articulate the threat model.

**Threat model.** These endpoints are qualitatively more dangerous than health/metrics: - **heapdump** streams the raw heap — every String, token, password, session, key currently in memory. A single unauthenticated GET is a full credential/PII exfiltration. - **threaddump** exposes stack traces, class/method names, and internal structure — useful reconnaissance for an attacker and occasionally leaks argument-ish detail. - **httpexchanges** can hold request/response data (and, if misconfigured to include COOKIE_HEADERS/AUTHORIZATION_HEADER, live credentials). **Layered hardening.** 1. **Minimal exposure.** Expose over the web only what infra needs: `management.endpoints.web.exposure.include=health` (plus `info`/`prometheus` if scraped). Do **not** use `*` in production. Diagnostic endpoints stay unexposed (or exposed only on the management port below). 2. **Separate management port.** Set `management.server.port` to a different port from the app, and bind it to an internal interface with `management.server.address` (e.g. a private IP). Now the public HTTP listener physically cannot serve `/actuator/heapdump`; only something on the internal network can reach the management port. This is the single most effective control. 3. **AuthN/AuthZ.** Secure actuator routes with Spring Security. Use `EndpointRequest.toAnyEndpoint()` (optionally `.excluding(HealthEndpoint.class)`) and require an operator authority: ```java http.securityMatcher(EndpointRequest.toAnyEndpoint()) .authorizeHttpRequests(a -> a.anyRequest().hasRole("ACTUATOR")) .httpBasic(withDefaults()); ``` Health can stay permitted for probes. Even behind an internal port, require auth (defense in depth). 4. **Per-endpoint access control.** Spring Boot 3.4+ supports `management.endpoint.<id>.access` (`none`/`read-only`/`unrestricted`; older Boot used `.enabled`). Disable what you don't need — e.g. `management.endpoint.heapdump.access=none` unless an incident requires it, then enable temporarily. 5. **Network / mesh.** Restrict the management port with firewall rules, security groups, NetworkPolicies, or a service mesh so only the ops jump-host / observability plane can reach it. Kubernetes: put actuator on a port that's not in the public Service, or gate with NetworkPolicy. 6. **httpexchanges hygiene.** Never include COOKIE_HEADERS/AUTHORIZATION_HEADER in `management.httpexchanges.recording.include`; keep the buffer small; prefer proper tracing/APM for real observability. **Heap-dump operational discipline.** Pulling a live heap dump on a hot node causes a stop-the-world pause proportional to heap size and produces a multi-GB file. Prefer: capture from a **drained/replica** instance, or rely on `-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=...` so the JVM writes one at the failure moment without you loading the live node. Treat the resulting `.hprof` as a **secret artifact**: transfer over TLS, store encrypted, restrict access, and delete after MAT analysis. Sanitize/redact is effectively impossible, so control the file's lifecycle instead. **Auditing & rate limiting.** Log and alert on access to these endpoints; consider rate-limiting heapdump to prevent disk-fill / DoS. Treat any access outside a known incident as suspicious. **Summary stance.** Public: `health` only. Internal & authenticated: `threaddump`, `httpexchanges`. On-demand & tightly controlled: `heapdump`. The default of 'only health web-exposed' exists for exactly this reason — don't override it carelessly with `exposure.include=*`.

  • Why is putting actuator on a separate management port often more valuable than authentication alone?
    Binding management.server.port/address to an internal interface means the public listener physically cannot serve heapdump/threaddump — an internet client can't even reach the route. It removes the endpoint from the public attack surface entirely, and you still add auth on top for defense in depth.
  • What's a safer way to obtain a heap dump in production than calling the endpoint on a live hot node?
    Capture it from a drained/replica instance out of rotation, or configure -XX:+HeapDumpOnOutOfMemoryError so the JVM writes an .hprof automatically at OOM — avoiding a stop-the-world live dump under load — then handle the file as a secret.
  • Why should you never add AUTHORIZATION_HEADER or COOKIE_HEADERS to httpexchanges recording?
    Those headers carry live credentials/session tokens; recording them stores exploitable secrets in the in-memory buffer, visible to anyone who can read the endpoint — a credential-leak risk with no upside for debugging.

saying these in an interview costs you the question

  • Using management.endpoints.web.exposure.include=* in production
  • Exposing heapdump on the public port with no auth 'because it's handy'
  • Believing you can redact secrets out of a heap dump
  • Thinking network isolation replaces the need for authentication (skip defense in depth)

context