Spring MVC Data Binding (Spring4Shell class)
A Spring MVC controller binds an untrusted request straight onto a command object with no field allowlist, so Spring's DataBinder walks arbitrary bean properties from the request. This is the mechanism CVE-2022-22965 (Spring4Shell) abused to reach class.module.classLoader.* and write a web shell.
What Vulkro detects
A framework-shape heuristic, not a taint proof. The detector cannot see the JDK version or the servlet container, so both rules are Medium severity.
SPRING-DATABIND-001 (Medium) fires on a @Controller / @RestController mapping method that binds a @ModelAttribute command object in a file with no setAllowedFields / setDisallowedFields allowlist.
SPRING-DATABIND-002 (Medium, lower confidence) fires on the same shape where the command object is an unannotated custom POJO parameter, which Spring also binds.
Suppression and non-matches: a file that declares an @InitBinder allowlist (any setAllowedFields or setDisallowedFields call) is treated as mitigated and stays silent. @RequestBody (which goes through Jackson, not the DataBinder), @RequestParam, @PathVariable, and framework or simple parameter types (Model, BindingResult, HttpServletRequest, String, primitives) never fire.
Findings land in the Software and Data Integrity Failures rollup, which is the category the detector emits.
Remediation. Add a controller-local @InitBinder that calls DataBinder.setAllowedFields(...) with the exact properties the form may write, or bind to a purpose-built DTO that has no fields beyond the ones the endpoint owns. Keep the framework patched as well: the allowlist is the documented mitigation, not a substitute for the fix.
Non-compliant code (examples)
Spring MVC - command object bound with no allowlist
@Controller
public class ProfileController {
@PostMapping("/profile")
public String save(@ModelAttribute Profile profile) {
repo.save(profile); // DataBinder walks whatever the request names
return "ok";
}
}
Compliant code (examples)
Spring MVC - @InitBinder allowlist constrains the bind
@Controller
public class ProfileController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setAllowedFields("displayName", "avatarUrl");
}
@PostMapping("/profile")
public String save(@ModelAttribute Profile profile) {
repo.save(profile);
return "ok";
}
}
See also
- Confidence model - what
High,Medium, andLowmean for findings in this category. - Safety - what Vulkro does and does not access on your machine.
References
This page is generated by vulkro rules export <out-dir> from Vulkro's built-in detector catalogue. Edits made by hand are overwritten on the next regeneration.