Skip to content
>_ITDITDWeb Security Platform

By framework

Spring Boot security — a production hardening reference

A Spring Boot production-hardening reference: a priority checklist plus dependency CVEs (Log4Shell), production config/secrets, Spring Security authorization, Actuator exposure, deserialization, and SSRF. Defensive, no attack steps.

Published 2026-07-02 Updated 2026-07-02 7 min read

For: anyone running a Java / Spring Boot app. No attack steps here — this is a working reference for hardening: a priority-ordered checklist, per-area guidance, and self-verification. For the cross-framework picture, see the security-by-framework hub.

Priority-ordered hardening checklist

Do this table top-down. P0 is a prerequisite, P1 is the most frequent source of incidents, P2 is ongoing operational hygiene.

P0 ── Prerequisite (do first)

Dependency CVE monitoring + fast patching / no error detail in production / externalize secrets

P1 ── Top source of incidents

Spring Security authorization (default-deny, owner checks) / reduce Actuator & management exposure

P2 ── Operational hygiene

Unsafe deserialization / headers, CSRF, session / SSRF

Harden from the foundation up: P0 (prerequisite) → P1 (top source of incidents) → P2 (operational hygiene).
PriorityControlSpecifics (Spring Boot)
P0Dependency CVE monitoringosv-scanner / dependency-check; judge by running version, patch fast (Log4Shell-class)
P0Production errorsDon't expose stack traces (server.error.include-stacktrace=never, etc.)
P0Externalize secretsConnection info/keys from env/Vault, not hardcoded config. Don't commit to the repo
P1Explicit authorizationDefault-deny + method security (@PreAuthorize) + owner checks
P1Reduce Actuator exposureMinimal exposure (e.g. health) + auth required + separate port/boundary. Don't expose env/heapdump
P1DeserializationDon't natively deserialize untrusted data. Don't let SpEL evaluate input
P2InjectionBind with JPA/JdbcTemplate. Never build queries by string concatenation
P2Headers/CSRF/sessionSpring Security headers (HSTS, etc.), CSRF, cookie attributes, session fixation
P2SSRFAllowlist server-side fetches + block internal IPs/metadata

1. Dependency CVEs and the ecosystem (P0)

Precisely because Spring is so widely used, a dependency-library flaw cascades to everyone at once. Log4Shell is the symbol of that.

2. Production config and secrets (P0)

  • In production, don't expose error detail (stack traces) — reduce clues that leak internal structure and dependency versions.
  • Keep secrets like connection info and keys out of application.properties/yml, injecting from env or a secret manager (Vault, etc.). Don't commit them to the repo (→ .env files and secrets).
  • Don't enable dev tools (devtools, etc.) in production.

3. Spring Security authorization (P1 — the top source)

Common (dangerous)

  • loose defaults, not designed as explicit allow
  • guarded by URL patterns only, no method/owner check
  • authenticated, but "logged in = allowed"
  • a config gap lets some endpoint pass through

Correct

  • default-deny (only what you explicitly allow passes)
  • method authorization (@PreAuthorize, etc.) + owner checks
  • verify permission/owner on every read/update/delete path
  • build authorization explicitly, not left to defaults

See what IDOR is. Authentication and authorization are different; authorize close to the data.

4. Actuator and management endpoints (P1)

  • Restrict exposed Actuator endpoints to the minimum (e.g. just health).
  • Require authentication/authorization, and keep them on a separate port / network boundary unreachable from outside.
  • Don't expose sensitive endpoints like env, heapdump, or loggers (info leak / a stepping stone for operations).

5. Unsafe deserialization and expression evaluation (P2)

  • Don't natively deserialize untrusted data (it can lead to RCE under the right conditions). Verify provenance and restrict to a safe format like JSON where needed (→ what RCE is).
  • Don't let templates or SpEL evaluate user input. Validate input with Bean Validation, etc.

6. Injection and data access (P2)

  • SQL: bind with JPA / JdbcTemplate; never build queries by string concatenation (→ what SQL injection is).
  • When emitting HTML from a template, run output encoding and don't embed user input directly (XSS defense).

7. Headers, HTTPS, session (P2)

  • Use Spring Security's security headers (HSTS on HTTPS, etc.). Check your own site with the security headers checker.
  • Force HTTPS. Behind a load balancer, configure it to detect the correct scheme/client IP.
  • Set Secure/HttpOnly/SameSite on cookies, keep CSRF protection (on by default for browser sessions; if you disable it for APIs, pair with alternative protections), and regenerate the session on login.

8. SSRF and server-side fetches (P2)

  • Server-side fetching of user-supplied URLs should restrict targets to an allowlist and block reaching internal IPs / cloud metadata at connection time (→ what SSRF is).

Verify: is your Spring Boot actually hardened?

Building it isn't the end — it's done only once you've checked. These are defensive self-checks against your own environment.

1

Actuator isn't exposing sensitive endpoints

In production, confirm /actuator doesn't expose env/heapdump, etc., and that it's authenticated.
2

Errors don't leak internals

Trigger an error and confirm no stack trace is shown externally.
3

Authorization holds

In a test environment, request another user's resource and confirm it is denied (read/update/delete paths).
4

Dependencies and headers

Confirm the dependency scan (osv-scanner/dependency-check) is clean, and that HTTPS/HSTS are present via the headers checker.

This site's view: on a hardened foundation, dependencies and surface decide it

Spring is a solid foundation, but precisely because it's so widely used, a dependency-library flaw cascades to everyone at once. Log4Shell is the symbol of this, and the core defense is less a specific setting than the operational habit of machine-monitoring dependencies, judging by the running version, and patching fast. Alongside that, keep the handy management endpoints (Actuator) off the public surface and don't leave authorization to defaults. This site is a different stack, but the principle is identical — dependency freshness, minimal public surface, explicit authorization work regardless of framework.

FAQ

QWhat should I do first to secure Spring Boot?
A

The three P0 items: (1) machine-monitor dependency CVEs and patch fast, judging by the running version (with Log4Shell, a foundational library cascades to many apps at once, so keeping up matters); (2) don't expose detailed errors (stack traces) in production; (3) externalize secrets (connection info, keys) instead of hardcoding them in config. Next, move to Spring Security authorization and reducing Actuator exposure.

QWhat should I watch for with Actuator?
A

Actuator provides management endpoints for runtime info and diagnostics, but if exposed it can leak internals and, depending on config, become a stepping stone for operations. In production, restrict exposure to the minimum (e.g. just health), require authentication and authorization, and keep it on a separate port / network boundary unreachable from outside. Don't expose sensitive endpoints like env, heapdump, or loggers.

QHow do I prepare for a dependency flaw like Log4Shell?
A

Log4Shell is the classic case of a widely-inherited logging library's flaw cascading to many apps at once. The core preparation is to machine-monitor dependency CVEs and patch fast, judging by the running version (osv-scanner, OWASP dependency-check, etc.) — decide on the version actually built, not the pom.xml/gradle declaration. Least privilege and network segmentation shrink the blast radius too.

QHow should I write Spring Security authorization safely?
A

Lean the default toward deny (only what you explicitly allow passes), don't rely on URL patterns alone, and use method-level authorization (@PreAuthorize, etc.) where appropriate. On top of login (authentication), implement an ownership check that the target resource truly belongs to the user. Config gaps become privilege-escalation holes, so build authorization explicitly.

QWhy is unsafe deserialization dangerous?
A

Restoring untrusted data via native Java deserialization can, under the right conditions, lead to remote code execution (RCE). Don't restore externally-sourced data as-is — verify provenance and restrict to a safe format like JSON where needed. Likewise, don't let templates or the expression language (SpEL) evaluate user input.