Safeguard
Incident Analysis•

Would your org have caught Spring4Shell? A control checklist

A practical checklist to test whether your inventory, patching and detection would have caught Spring4Shell (CVE-2022-22965) fast, and what to fix if not.

Safeguard Security Team
4 min read

Spring4Shell, CVE-2022-22965, was a remote code execution flaw in Spring Framework data binding. You would have caught it quickly if you could answer three questions in hours: where do we run Spring, which versions and packaging, and is any of it internet facing. This checklist tests those controls without blaming anyone.

What happened, briefly?

Spring published its advisory on March 31, 2022. It describes remote code execution through data binding in Spring MVC or WebFlux applications on JDK 9 or higher. Affected versions were Spring Framework 5.3.0 through 5.3.17 and 5.2.19 and earlier. Fixes landed in 5.3.18 and 5.2.20.

The advisory is careful about conditions. The specific exploit needed JDK 9 or higher, Apache Tomcat, deployment as a WAR, and a spring-webmvc or spring-webflux dependency. Applications deployed as the default Spring Boot executable jar were not vulnerable to that specific exploit, though the advisory warns that the underlying issue is more general and other exploitation paths may exist.

CISA added the CVE to its Known Exploited Vulnerabilities catalog on April 4, 2022, with a remediation due date of April 25, 2022 for federal agencies.

Those conditions are the reason the response was hard. Many teams had Spring everywhere and had to work out which of it matched.

Control 1: Could you find every Spring app?

Spring often arrives as a transitive dependency, not something a team chose. Ask yourself whether you keep a current software bill of materials per service, and whether you can query it by package and version.

Test: pick a library at random today and time how long it takes to list every service that includes it. If the answer is a week of emails, that is your gap.

Control 2: Could you tell which instances were exposed?

The advisory's conditions turn into a query: JDK version, servlet container, packaging type, and whether the app takes external requests. Do your inventory records include runtime and packaging, or only the library name?

Test: for one framework you run, can you filter by JDK 9 or higher and by WAR deployment?

Control 3: Did you have an exploited vulnerability feed wired to action?

KEV exists to tell defenders what is being exploited. A team that gets a KEV addition into a ticket queue, with an owner and a clock, moves faster. Check who watches the catalog and where an addition goes. CISA's guidance on the catalog is to use it as an input to vulnerability prioritization.

Control 4: Could you patch a framework upgrade safely?

An upgrade from 5.3.17 to 5.3.18 is small, but teams on end of life lines faced a bigger jump. Ask what share of your services have automated tests that would tell you an upgrade is safe, and how long a hotfix takes from commit to production.

Control 5: Could you detect an attempt?

Look at what your edge and application logs record. Could you search request parameters across services for a short period back in time? Retention and searchability decide whether you can say "no one tried" or only "we do not know."

Control 6: Did someone own the decision?

Incidents slow down when nobody can say yes to an emergency change. Name an owner for urgent third party advisories, and write down what authority they have.

Why this is not a story about blame

The conditions were subtle, the library is everywhere, and many affected teams had done reasonable work. The point of a retrospective is to find which questions took too long to answer, then shorten them.

What to do

  1. Pick a library and time the "who uses this" query across all services.
  2. Add runtime, packaging and exposure fields to your inventory.
  3. Route KEV additions into the ticket system with an owner.
  4. Measure commit to production time for an emergency dependency upgrade.
  5. Confirm request logs are searchable for at least the period your policy states.
  6. Name an owner for emergency advisories and write down their authority.
  7. Repeat the drill each quarter with a different library.

Quick check

Was every Spring application vulnerable to Spring4Shell?

No. The specific exploit in the advisory needed JDK 9 or higher, Tomcat, a WAR deployment and the affected Spring versions. Default Spring Boot executable jars were not vulnerable to that specific exploit.

Which versions fixed it?

Spring Framework 5.3.18 and 5.2.20, according to the Spring advisory.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.