Start with the deployed shape of the application
Spring's 31 March 2022 advisory for CVE-2022-22965 described remote code execution through data binding. The reported exploitation scenario combined several conditions: JDK 9 or later, the relevant Spring web dependency, and a traditional WAR deployment on Tomcat. The default Spring Boot executable-JAR deployment was not vulnerable to that specific exploit. The maintainers also cautioned that the underlying issue was more general than the demonstrated route.
This is a good example of why a vulnerability decision needs a deployment record. A dependency name can put an application into a review queue. It cannot, by itself, establish whether all the conditions for a particular exploit are present.
Turn the advisory into a conjunction of conditions
A useful triage record follows the conditions in the maintainer's document instead of compressing them into a yes-or-no judgement about the entire framework.
| Condition | Read-only evidence | Typical source of confusion |
|---|---|---|
| Framework release | Resolved dependency report for the deployed build | Reading the intended version from an unbuilt branch |
| Java runtime | Runtime identity in the actual workload | Checking a developer laptop |
| Packaging and container | Deployment manifest and application artefact | Treating every Spring Boot service as the same packaging model |
| Relevant web behaviour | Application configuration and code review | Assuming all request parsing uses the same binding mechanism |
Record a negative finding narrowly. “Not vulnerable to the documented WAR/Tomcat scenario” says something different from “cannot be affected by any variant of this weakness.” The narrower statement is more useful because another reviewer can see which condition supported it.
Historical fixes and current maintenance are different decisions
The original fixed Spring Framework releases were 5.3.18 and 5.2.20.RELEASE. The early announcement also recorded related Spring Boot releases and subsequent container-side mitigation information. These are response-history boundaries, not recommended maintenance targets for a system being operated years later.
For a currently maintained application, follow the supported framework and runtime release policies. If a distribution or supplier provides a backport, retain its advisory and package identity rather than comparing an upstream version string in isolation.
The early announcement was updated as the maintainers refined deployment guidance and workarounds. That history is useful evidence in its own right: an assessment based on the first hours of a disclosure may need another look after conditions are clarified. A ticket should identify which revision of the advisory informed its decision.
Build a deploy-time answer once
Teams often repeat the same emergency discovery work for each Java vulnerability. A modest deployment inventory can remove much of that delay. For each service, retain the application release, resolved framework dependencies, runtime line, package shape and container type. Attach the record to the deployed artefact, not merely to the repository.
This does not require publishing a detailed software bill of materials for every internal system. It requires making the necessary facts available to the service's own responders. If the record cannot distinguish a WAR from an executable JAR, it is too coarse for this incident class.
When a component changes, update the record as part of the deployment. An inventory that was accurate before a migration can produce a misleading negative assessment afterwards. Security triage should be able to identify both the current state and the state during the relevant exposure window.
What the Log4Shell comparison can and cannot tell us
Inspect an artefact without starting the application
For an application archive already obtained from the organisation's trusted build process, an administrator can list its entries using standard archive tools:
unzip -l application.war 'WEB-INF/lib/spring-*.jar'
unzip -p application.jar META-INF/MANIFEST.MF
Use the real local artefact path in place of the example filename. The first command helps locate framework JAR names in a conventional WAR layout; the second reads a JAR manifest. Neither command launches the application or sends a request to it.
The output still needs interpretation. A filename may be renamed, a dependency may be shaded or bundled differently, and a manifest does not prove the runtime configuration of the deployed service. Join this evidence to the build's dependency report and the deployment record. If the archive layout differs, document that difference rather than treating an empty listing as proof that Spring is absent.
Avoid resolving an unfamiliar project's build merely to discover dependencies during an incident. Build wrappers and plugins execute code and may download additional material. A trusted, already produced dependency report is a different kind of evidence from executing a newly acquired repository.
Preserve the reason for a negative assessment
A useful record states the condition that was not met, the evidence used and the deployment identity it describes. For example, a packaging-based assessment applies to that packaged release, not automatically to a later migration of the same repository onto another container.
Reassess when the deployment model changes or the advisory adds a relevant vector. This is not an invitation to reopen every historical finding on a schedule without cause. It is a rule for keeping an assessment tied to the assumptions that made it valid.
Log4Shell involved a logging implementation and attacker-controlled input; Spring4Shell involved data binding and deployment-specific conditions. Their similar nicknames do not establish similar reachability or remediation.
The useful shared lesson is that a dependency inventory should be joined to runtime and deployment evidence. The useful difference is the set of conditions that join must explain. Importing a previous incident's emergency checklist without revisiting those conditions can generate both unnecessary outages and missed exposure.
For a technical team, the best closure statement is consequently specific: the exact release was assessed, the relevant deployment conditions were established, the chosen fix or vendor-backed assessment was verified, and the running workload matches that record.
