Setting JavaBean properties from untrusted user input can allow an attacker to manipulate arbitrary object properties, including sensitive internals such as class.classLoader.

Why is this an issue?

JavaBean property population functions such as BeanUtils.populate(), BeanUtils.setProperty(), BeanUtilsBean.populate(), and BeanUtilsBean.setProperty() from Apache Commons BeanUtils, and BeanWrapper.setPropertyValue() and BeanWrapper.setPropertyValues() from Spring, allow setting arbitrary bean properties by name. When the property names or values are derived from untrusted input without validation, an attacker can set sensitive properties — for example, class.classLoader — and use them to load and execute malicious code.

What is the potential impact?

If successfully exploited, this vulnerability can lead to remote code execution, full application compromise, data exfiltration, or lateral movement within the network.

How to fix it

Code examples

Noncompliant code example

Company bean = new Company();
HashMap map = new HashMap();
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
    String name = (String) names.nextElement();
    map.put(name, request.getParameterValues(name));
}
BeanUtils.populate(bean, map); // Noncompliant: "map" is populated with data coming from user input, here "request.getParameterNames()"

Compliant solution

Company bean = new Company();
HashMap map = new HashMap();
Set<String> allowedProperties = Set.of("name", "address"); // define allowed properties
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
    String name = (String) names.nextElement();
    if (allowedProperties.contains(name)) {
        map.put(name, request.getParameterValues(name));
    }
}
BeanUtils.populate(bean, map);

Resources

Articles & blog posts

Standards