Security implications of the Spring DataBinder
Today I was reviewing the security of a simple business application and found the following (simplified) controller:
public class UserEditController extends CancellableFormController {
protected SecurityService securityService;
protected ModelAndView onSubmit(...) throws Exception {
User user = (User)command;
securityService.updateUser(user);
return getSuccessView();
}
@Required
public void setSecurityService(SecurityService securityService) {
this.securityService = securityService;
}
}
At first sight this seems a very common form-controller to edit a User object. The problem lies here in the fact that the User object has a few properties like “expireDate” and “accessLevel”. Experienced Spring users might see the security-problem now, others should check out the documentation for a hint:
Note that there are potential security implications in failing to set an array of allowed fields. In the case of HTTP form POST data for example, malicious clients can attempt to subvert an application by supplying values for fields or properties that do not exist on the form.
If you don’t set the allowedFields or disallowedFields property the DataBinder will bind all HTTP-parameters to the domainobject so a malicious user could post an accessLevel property changing their own accessLevel. Of course setting allowedFields everywhere seems like a lot of work, but Spring has made this quite easy. From the documentation:
Register fields that should be allowed for binding. Default is all fields. Restrict this for example to avoid unwanted modifications by malicious users when binding HTTP request parameters.Supports “xxx*”, “*xxx” and “*xxx*” patterns. More sophisticated matching can be implemented by overriding the isAllowed method.
So with these patterns there is no excuse to not restrict the properties to be bound.
