If you missed yesterday's article on Clean URLs you can find it here. Today I want to talk about how we can control what values get bound in an Action Bean when we submit a form. And once again;
Disclaimer - We know that other web frameworks have had some of these features in some form or fashion so please don't comment with "ZZZ Framework has been doing that for years.". We know. We get it.
The Stripes team has added a very useful annotation as well as some supporting changes to an existing annotation to provide a first line of defense against hackers. This annotation is @StrictBinding. This is a class level annotation and uses the @Validate annotation as support. First we can look at a basic example:
@StrictBinding
public class RegisterActionBean extends BaseActionBean {
private User user;
}
In this example any values submitted by a form to this action bean won't be bound at all. Hmm, not very useful. So lets tweak it a bit.
@StrictBinding(allow="*")
public class RegisterActionBean extends BaseActionBean {
private User user;
}
This will allow binding to any top level properties in user. However, nested properties are ignored. Not quite what we need yet. One more modification.
@StrictBinding(allow="**")
public class RegisterActionBean extends BaseActionBean {
private User user;
}
Alright, the double * in the allow attribute says bind everything, no matter how nested. Another way to achieve the same thing is to use defaultPolicy=Policy.ALLOW instead of "allow". If we need finer grained control we can also use the "deny" attribute.
@StrictBinding(allow="**", deny="user.role.id")
public class RegisterActionBean extends BaseActionBean {
private User user;
}
This allows everything to bind except for user.role.id because we don't want a new user to be able to specify their own security level by adding parameters sent to the server. That would be bad. And with that I think you can see the benefit of @StrictBinding. It is a good first line defense mechanism. But we're not done yet.
@StrictBinding all by itself can handle anything you need however the preferred way to control binding is with @StrictBinding + @Validate. Lets look at another example.
@StrictBinding
public class RegisterActionBean extends BaseActionBean {
@ValidateNestedProperties({
@Validate(field="username", required=true),
@Validate(field="password", required=true),
@Validate(field="firstName", required=true),
@Validate(field="lastName", required=true)
})
private User user;
}
First we turn off all binding using the simplest form of @StrictBinding. Then, we control the binding with validation. Any property being validated is bound. Everything else is ignored.
As always data should be sanitized but with the addition of @StrictBinding, Stripes provides a very elegant first line of defense against intruders.
3 comments:
Nice article. As far as I can tell your Stripes series is worth reading!
Do you think you could tag all your Stripes articles? I would like to have a simple (and easy) way how I can reference these articles on my blog :-)
Thanks very much lukas. All the stripes articles have been given labels:
java,stripes,framework
Strict binding seems to be the missing point in the securing Stripes. Great work.
Morten Matras
Post a Comment