XWork Plugin Complex Parameters and Security
Complex XWork Parameters
XWork allows the setting of complex parameters on an XWork action object. For example, a URL parameter of
formData.name=Charles will be translated by XWork into the method calls
getFormData().setName("Charles") by the XWork parameters interceptor. If
getFormData() returns null, XWork will attempt to create a new object of the appropriate return type using its default constructor, and then set it with
This leads to the potential for serious security vulnerabilities in XWork actions, as you can effectively call arbitrary methods on an Action object. This led to the Parameter Injection issues in Confluence Security Advisory 2008-10-14. In Confluence 2.9 this issue was worked around by filtering out all properties that were known to be dangerous, but for 2.10 a more complete solution that also protects against future vulnerabilities has been introduced.
Because this vulnerability (and its solution) can affect plugins, plugin authors must now take extra steps to support complex form parameters.
The @ParameterSafe Annotation
From Confluence 2.10 and onwards, complex parameters are not permitted unless they are accompanied by a Java-level annotation declaring that the parameter is "safe" for XWork to access. There are two ways to apply the annotation:
- If a getter method is annotated with the
@com.atlassian.xwork.ParameterSafeannotation, that method is accessable as a complex parameter
- If a class is annotated with the
@com.atlassian.xwork.ParameterSafeannotation, any complex parameter that is of that type is accessible
Only the initial method on the XWork action, or initial return value from the action class needs to be annotated, nested complex parameters do not need further annotation.
So in the example above, to make the formData parameter you would do one of the following:
By placing the
@ParameterSafe annotation on a method or class, you the developer are declaring that you have carefully inspected that code for potential vulnerabilities. Things to be careful of:
- DO NOT return live Hibernate persistent objects, as users may change values on them directly with parameters, and then those changes will be saved to the database automatically
- DO NOT return objects that contain setter methods that are used for anything but setting form parameter values, as those values will be reachable by URL parameter injection
- DO NOT return objects that have Spring-managed beans, live components, or hibernate objects accessible through getter methods, as they will be accessible to URL parameter injection
Your safest bet is that if you are using an object to store complex parameters, make it a dumb: just setters that store state in the object itself and no further behaviour. Any more functionality than that is dangerous.