Blog

Security implications of the Spring DataBinder

April 17, 2008 17:14 in Java, Technology

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.

Maven tomcat:run and context.xml

April 11, 2008 15:40 in Maven, Technology

I ran into a problem today: When using the command mvn tomcat:run (the maven tomcat plugin) to quickly run a Tomcat instance and edit some JSPs on the fly I noticed my application was unable to find it’s JNDI defined DataSource:

javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

But this DataSource is defined in the src/main/webapp/META-INF/context.xml default context file:

<Context>
        <Resource name="jdbc/dbname" auth="Container" type="javax.sql.DataSource"
                maxActive="100" maxIdle="30" maxWait="10000"
                username="username" password="pass" driverClassName="com.mysql.jdbc.Driver"
                url="jdbc:mysql://localhost/dbname?autoReconnect=true"/>
</Context>

So I searched the web for other people with these kind of issues and found a few mailinglist questions (all unanswered) here and here. And finally found out that it is just not possible to use a context.xml with the tomcat:run goal as it is still an open issue in the codehaus JIRA: #MOJO-594. So I hope this might save someone some time searching for how to get tomcat to pickup the context.