deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Spring Boot /actuator/env sanitizer misses secrets with non-standard names

A dev.to investigation published in English and Spanish shows Spring Boot's default /actuator/env masking only catches generic keywords, leaving custom-named secrets like DB_PASS exposed in plain text.

Spring Boot /actuator/env sanitizer misses secrets with non-standard names

The finding

A developer investigation published on dev.to in parallel English and Spanish versions argues that Spring Boot's built-in masking for the /actuator/env endpoint only protects property names that match generic security vocabulary — and that real-world leaks happen through names that don't.

According to the post, the sanitizer replaces a value with asterisks whenever a property key contains password, secret, key, token or credentials. Any key that avoids those words — DB_PASS instead of DB_PASSWORD, API_AUTH instead of API_TOKEN, or entries like WEBHOOK_SIGNING, PARTNER_SHARED_VALUE and INTERNAL_CIPHER — reaches the endpoint's JSON response without a single character masked.

Why the defaults fall short

The author's argument is not that the sanitizer is poorly written but that it is generic by design: it covers the words Spring's developers anticipated, not the dialect each team actually invents. Naming decisions get made under deadline pressure, and nobody returns later to add them to a masking pattern. The author reports seeing exactly this gap in code review: a shared-secret-style value fully visible in a staging configuration because its name never contained the word "secret".

The post also cites the official Spring Boot Actuator documentation, which confirms that values are sanitized before exposure and that the behavior is extensible through the SanitizingFunction interface, which replaced the older keyword-list Sanitizer approach in recent framework versions. What the documentation cannot supply is the catalog of names your project uses — auditing that remains the responsibility of whoever configures the application.

Authorization is not masking

A recipe the author sees repeated on forums and in inherited configurations is to enable management.endpoint.env.show-values=when-authorized and consider the problem solved. That setting governs who may view values; it says nothing about which values appear unmasked to those authorized viewers. The cost surfaces when an internal role — a monitoring service or an operations dashboard — legitimately reads the endpoint and encounters credentials nobody thought to mask because the variable name missed the default pattern.

Extending the chain

The fix demonstrated in the post is a custom SanitizingFunction bean carrying a team-specific regular expression — the example uses a case-insensitive pattern matching pass, auth, signing, shared and cipher — that returns a masked value on a match and passes the data through otherwise. Spring Boot runs every registered function in order as a chain, and masking applies if any one of them decides it is warranted; the custom bean adds to the chain rather than replacing the defaults.

The author flags a related trap: teams using Vault or AWS Secrets Manager in production may still leave awkwardly named variables in application-staging.yml, and an inherited, overwritten custom regex can miss underscore or mixed-case variants of sensitive names.

Recurring mistakes

The post lists several failure modes seen in practice: treating authorization and sanitization as a single setting; copying a regex from an older project without adapting it to the current team's conventions; never writing a test that verifies an oddly named variable actually comes out masked; assuming the problem is production-only when staging and shared development environments often hold real third-party credentials for integration testing; and expecting a Spring Boot version bump to extend the pattern list, when the framework only maintains its own default keywords from release to release.

Why it matters

The author's sharpest conclusion is that an unmaintained custom sanitizer can be worse than none at all, because it manufactures confidence where there is no coverage. If nobody periodically audits which property names appear in the code, disabling /actuator/env entirely is the safer call. For any team running Actuator endpoints beyond localhost, the practical takeaway is an audit of every key in application.yml and .env per environment, a sanitizer pattern that reflects the team's actual naming conventions, and a test proving that unconventional names get masked — because the plaintext path never closes itself.

  • #spring-boot
  • #security
  • #actuator
  • #java
  • #configuration

Related posts