[← 02 Boot 4 changes](02-boot-4-changes.md) · **03 · The endpoint catalogue** · [04 Securing Actuator →](04-securing-actuator.md) # 03 — The endpoint catalogue The table in the [README](../README.md#endpoints) is the reference. This chapter covers the three endpoints people get wrong. ## `env` does not leak values The oldest Actuator scare story is "`/actuator/env` dumps your database password". In Spring Boot 4 it does not. From [`output/03-open-actuator-leak.txt`](output/03-open-actuator-leak.txt), with no credentials sent at all: ```json {"source":"Config resource 'class path resource [application.yaml]' ...","value":"******"} ``` That is `spring.datasource.password`, and it is also `acme.partner.credential` — a property whose name matches none of the classic `password`/`secret`/`token`/`key` patterns. Both masked. Masking is not pattern matching on key names. It is `management.endpoint.env.show-values`, which defaults to `never`. Set it to `always` and both come back in plaintext: ``` acme.partner.credential S3CRET-partner-credential spring.datasource.password not-a-real-password-but-watch-what-/actuator/env-does-with-it spring.security.user.password ops-password ``` So the risk with `env` is real but it is a *configuration* risk, not a default. The `origin` field is also worth knowing about — it reports the exact file and line a property came from, which is genuinely the fastest way to answer "where is this value coming from" in a service with six property sources. ## `heapdump` is not exposed by `include: "*"` This surprises people who learned Actuator on Boot 2. ``` $ curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/actuator/heapdump 404 ``` …with `management.endpoints.web.exposure.include: "*"` and a `permitAll` security chain. `management.endpoint.heapdump.access` defaults to `none`, and exposure does not override access. Reading Spring Boot's own `spring-configuration-metadata.json` for every `management.endpoint.*.access` key gives exactly two endpoints defaulting to `none`: | Endpoint | `access` default | |---|---| | `heapdump` | `none` | | `shutdown` | `none` | | everything else | `unrestricted` | Turn it on and the story changes completely — [`output/04-heapdump-leak.txt`](output/04-heapdump-leak.txt): ``` status=200 bytes=59065395 type=application/octet-stream $ strings /tmp/heap.hprof | grep -c 'S3CRET-partner-credential' 1 $ strings /tmp/heap.hprof | grep -o 'not-a-real-password[^"]*' | head -1 not-a-real-password-but-watch-what-/actuator/env-does-with-it ``` 59 MB containing, in plaintext, both properties that `/actuator/env` had just masked. Sanitisation is a rendering feature of one endpoint. It is not a security boundary. ## `loggers` is a write endpoint `GET /actuator/loggers/{name}` is harmless. `POST` is not: ``` $ curl -X POST -H 'Content-Type: application/json' \ -d '{"configuredLevel":"TRACE"}' /actuator/loggers/org.springframework status=204 ``` 204, no credentials. An attacker who can do that has a denial-of-service primitive (TRACE on a busy service will fill a disk) and, depending on your logging configuration, a way to get request bodies and headers written to a file they may be able to read through another channel. `beans` (426 entries here) and `mappings` (30 servlet mappings) are read-only but are pure reconnaissance — they describe your entire application's shape. --- [← 02](02-boot-4-changes.md) · **03** · [04 Securing Actuator →](04-securing-actuator.md)