skip to content

Why do Spring Boot Actuator endpoints need to be secured, and what is exposed by default?

level: juniorimportance: must knowfreq 70%

answer

  1. only /health exposed by default over HTTP
  2. exposure != authentication
  3. /env, /configprops, /heapdump leak secrets
  4. /loggers, /shutdown are write actions
  5. avoid exposure.include=*

basics

~20 s

Actuator endpoints like /env, /configprops, /heapdump, /threaddump and /loggers reveal internal state, config values and secrets, and some let you change runtime settings. Leaving them open lets attackers read secrets or tamper. Restrict them to admins.

solid answer

~30 s

Actuator exposes operational endpoints under /actuator. Some are read-only but sensitive: /env and /configprops show configuration (potentially DB passwords, API keys), /heapdump and /threaddump can leak in-memory data, /mappings and /beans reveal internals. Others are write/action endpoints: /loggers changes log levels, /shutdown stops the app. By default only /health is exposed over HTTP; you opt others in via management.endpoints.web.exposure.include. But once exposed they're unauthenticated unless you add Spring Security. The standard fix is a SecurityFilterChain that requires an admin role for EndpointRequest.toAnyEndpoint(), plus value sanitization on /env and /configprops. Never expose the full set publicly.

code

yaml · 10 lines
yaml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics   # opt-in explicitly; never '*' in prod
  endpoint:
    health:
      show-details: when-authorized    # hide details from anonymous callers
    shutdown:
      enabled: false                   # keep the kill switch off

go deeper

for a junior

Should know actuator endpoints can leak secrets and that only /health is exposed by default.

for a middle

Should distinguish exposure from authorization and name the dangerous endpoints.

for a senior

Should describe the layered fix: minimal exposure + security filter chain + value sanitization.

for a principal

Should frame default-deny posture and treat exposure/security/network as independent controls.

**What Actuator is.** Spring Boot Actuator (`spring-boot-starter-actuator`) adds production-ready HTTP endpoints under a base path (default `/actuator`) for monitoring and management: `health`, `info`, `metrics`, `env`, `configprops`, `beans`, `mappings`, `loggers`, `threaddump`, `heapdump`, `shutdown`, and more. **Why they are dangerous.** - **Data-leak endpoints (read):** `/actuator/env` dumps the entire Spring `Environment` — every property source including system env vars and application config, which often contains `spring.datasource.password`, cloud credentials, JWT secrets. `/actuator/configprops` dumps all `@ConfigurationProperties` beans with their bound values. `/actuator/heapdump` downloads a full JVM heap dump (every object in memory — tokens, PII). `/actuator/threaddump`, `/actuator/beans`, `/actuator/mappings` reveal code structure useful for further attacks. - **Action endpoints (write):** `/actuator/loggers/{name}` (POST) changes log levels at runtime; `/actuator/shutdown` (POST, disabled by default) stops the application — a trivial DoS if enabled and open. **Default posture.** Since Spring Boot 2.x, over **HTTP** only `health` is exposed by default (`info` too in some setups). Over JMX defaults differ. You explicitly opt endpoints in with `management.endpoints.web.exposure.include=health,info,metrics` (or `*` for all — dangerous). **Exposure is not authentication:** an exposed endpoint is reachable by anyone unless Spring Security guards it. **The fix, in layers:** 1. **Expose only what you need.** Keep `exposure.include` minimal; avoid `*` in production. 2. **Authenticate + authorize.** Add `spring-boot-starter-security` and a `SecurityFilterChain` requiring a role (e.g. `ROLE_ACTUATOR_ADMIN`) for `EndpointRequest.toAnyEndpoint()`. 3. **Sanitize values.** `/env` and `/configprops` mask secret-looking keys by default and, since Boot 3, hide **all** values unless `management.endpoint.env.show-values` / `configprops.show-values` is set to `ALWAYS` or `WHEN_AUTHORIZED`. 4. **Network isolation.** Optionally run management on a separate port (`management.server.port`) bound to an internal interface. **Gotcha:** Real breaches have happened where teams set `exposure.include=*` for convenience and shipped it, leaving `/env` and `/heapdump` world-readable. Exposure config and security config are independent — you need both correct.

  • Does adding an endpoint to exposure.include make it secure?
    No. Exposure only controls whether an endpoint is reachable over the web transport. Access control is a separate concern handled by Spring Security; without a filter chain, an exposed endpoint is open to anyone.
  • Which two endpoints are the most notorious for leaking secrets?
    /actuator/env and /actuator/configprops, because they render bound configuration values (DB passwords, API keys). /heapdump is also severe since it dumps all in-memory objects.

saying these in an interview costs you the question

  • Thinking all endpoints are exposed by default (only health is over HTTP)
  • Believing exposure.include also enforces authentication
  • Assuming actuator is safe because it's 'just monitoring'
  • Enabling exposure.include=* in production

context