Wednesday, May 14, 2008

Struts InvalidCancelException

2.1. Bug 38374 - Validation always skipped with Globals.CANCEL_KEY




2.1.1. Issue: Cancel Processing



The Struts <html:cancel> tag sets a request parameter (org.apache.struts.taglib.html.Constants.CANCEL) which causes validation to be skipped.


Spoofing this request parameter however, could be used maliciously in order to circumvent an applications validation and proceed with the request processing with erroneous and potentially damaging data.


See [WWW] Bug 38374 for full details.



2.1.2. Resolution: Cancellable Property



A new cancellable property has been introduced which indicates whether an action is allowed to be cancelled or not. In Struts 1.2.9 this is set to true or false for an action in the struts-config.xml using the <set-property> notation. From Struts 1.3.x a new cancellable attribute has been added to the <action> element.


Now any action where the cancellable property is not set to true will throw an InvalidCancelException.



2.1.3. Upgrade Implications



Any existing applications that use the Cancel processing will need to modify their struts-config.xml to set the cancellable property for actions which require it.


In Struts 1.2.9 the <set-property> is used to set the cancellable property for an action....



<action path="/fooAction"
input="/foo.jsp"
validate="true">
<set-property property="cancellable" value="true"/>
<forward name="success" path="/bar.jsp"/>
</action>

From Struts 1.3.x a new cancellable attribute can be used....



<action path="/fooAction"
input="/foo.jsp"
validate="true"
cancellable="true">
<forward name="success" path="/bar.jsp"/>
</action>

In both Struts 1.2.9 and Struts 1.3.x an exception handler can be configured to handle the InvalidCancelException



<action path="/fooAction"
input="/foo.jsp"
validate="true"
cancellable="true">
<forward name="success" path="/bar.jsp"/>
<exception key="errors.cancel"
type="org.apache.struts.action.InvalidCancelException"
path="/foo.jsp"/>
</action>


2.1.4. Test Cases



This bug was tested using the struts-examples webapp (see struts-examples.war in the binary distribution). If you fire up the examples webapp, select the Taglib Test Pages link, then select the <html:cancel> link you will be presented with a page where you can try the Cancel button for four different configurations.