Wicket SecureForm
posted by mighty Igor on the Wicket-User list:
Here is a simple demonstration of how to prevent “Cross-Site Request Forgery”
| Java | | copy | | ? |
/** |
* Form that uses a random uuid token in order to prevent nasty people from messing around (also known as cross site request forgery) ;) |
* @author igor vaynberg |
*/ |
class SecureForm extends Form |
{ |
public SecureForm(final String id) |
{ |
super(id); |
} |
private static final long serialVersionUID = 1L; |
private static final String TOKEN_NAME = "SECURE_FORM_TOKEN"; |
private String token; |
@Override |
protected void onBeforeRender() |
{ |
super.onBeforeRender(); |
this.token = UUID.randomUUID().toString(); |
} |
@Override |
protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) |
{ |
super.onComponentTagBody(markupStream, openTag); |
getResponse().write("<input type='hidden' name='" + this.TOKEN_NAME + "' value='" + this.token + "'/>"); |
} |
@Override |
public boolean process() |
{ |
if (!this.token.equals(getRequest().getParameter(this.TOKEN_NAME))) |
{ |
throw new IllegalStateException("token mismatch"); |
} |
return super.process(); |
} |
} |


I used the SecureForm, but I don’t want to allow multiple Submits with one Token, so I chanded the process method
@Override
public void process(IFormSubmittingComponent submittingComponent) {
if (token == null || !token.equals(getRequest().getParameter(TOKEN_NAME))) {
throw new IllegalStateException("Security Token mismatch, possible breach detected.");
} else {
IRequestTarget requestTarget = RequestCycle.get().getRequestTarget();
if (requestTarget != null && !(requestTarget instanceof AjaxRequestTarget)) {
token = null;
}
super.process(submittingComponent);
}
}
But as you can see, I am not able to generate a new Token when I get an Ajax Request, so I allow multiple Submits within Ajax Form Submitting Behaviors.
Any ideas how I can replace the Token within Ajax?
i don´t really get what you are trying to do. i´d say, test for conditions of special behaviour (AJAX) first, then fallback to
if (token == null || !token.equals(getRequest().getParameter(TOKEN_NAME)))
but probably, i lack understanding here. do you have a quickstart for me to investigate?
Is it ok to ignore the deprecated status of super.process call within process?
you can hook that token check into somewhere else, if you wanted:
process(IFormSubmittingComponent) or even
onFormSubmitted()
Thanks Uwe! process(IFormSubmittingComponent) calls process() anyway, and onFormSubmitted() is declared final so I guess I’ll stick with process(). I’m about to use the SecureForm technique in a couple of big apps, and don’t want to screw them up.
Steve
Best of Luck, then.