Be careful when setting bean properties using external data.
Java beans are classes that implement getters and setters for their fields in conformance with the JavaBeans specification. Libraries such as Apache's Commons BeanUtils use reflection to access fields and set or retrieve their values.
Managing data through beans is versatile, but can also reduce security. For example, a particular version of Apache's BeanUtils used within the Struts web framework was susceptible to certain class loader related attacks. This attack consisted of accessing the class
property of a bean, through which the ClassLoader
for that bean could be accessed. Obtaining a reference to a ClassLoader
can allow loading an attacker-defined class into the application, achieving arbitrary code execution.
This issue is raised if methods such as BeanUtils.populate()
or Spring's BeanWrapper.setPropertyValue()
are called with possibly unsanitized input.
class UserDataBean { /*...*/ }
@Override
void method() {
HashMap map = new HashMap();
Map<String, String[]> params = request.getParameterMap();
UserDataBean bean = new UserDataBean();
BeanUtils.populate(bean, params); // Insecure.
}
Sanitize any data that will pass into a JavaBean instance. How you do so will be very specific to your own requirements, but here are a few suggestions:
Map<String, String[]> finalParams = new HashMap<>();
for (Map.Entry<String, String[]> entry : params.entrySet()) {
if ( !allowedKeys.contains(entry.getKey())) continue; // Filter out unnecessary keys.
finalParams.put(entry.getKey(), entry.getValue());
}
BeanUtils.populate(bean, finalParams);
If any of the data in the request is used in the response, care must be taken to avoid injecting malicious data from the request into the response, as this could lead to a server-side injection attack.