Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WW-5468 Exempt ModelDriven Actions from @StrutsParameter requirement #1072

Merged
merged 4 commits into from
Oct 14, 2024

Conversation

kusalk
Copy link
Member

@kusalk kusalk commented Oct 12, 2024

WW-5468

The @StrutsParameter requirement was designed to protect against arbitrary getters and setters on the Action class from being invoked by users and/or attackers. However, if an Action is using a dedicated model object alongside the ModelDrivenInterceptor (which ensures the Action is not on the root of the value stack) much of this risk is mitigated. I suggest we exempt this specific scenario from requiring the @StrutsParameter annotation.

Closes #1071

if (action instanceof ModelDriven<?> && !ActionContext.getContext().getValueStack().peek().equals(action)) {
LOG.debug("Model driven Action detected, exempting from @StrutsParameter annotation requirement and OGNL allowlisting model type");
// (Exempted by annotation on com.opensymphony.xwork2.ModelDriven#getModel)
return hasValidAnnotatedMember("model", action, paramDepth + 1);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This conditional block and the added annotation on the ModelDriven interface comprise the core fix

if (paramDepth >= 1) {
allowlistClass(relevantMethod.getReturnType());
allowlistClass(propDesc.getPropertyType());
Copy link
Member Author

@kusalk kusalk Oct 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor fix here to ensure the specific model type is allowlisted rather than the type declared in the interface (Object.class) - thanks @lukaszlenart

@@ -44,7 +44,6 @@ public String getFoo() {
/**
* @return the model to be pushed onto the ValueStack after the Action itself
*/
@StrutsParameter(depth = 2)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed all these annotations on ModelDriven Action model getters as they are no longer required (not that they were being detected correctly previously)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced tabs with spaces to fix the janky formatting

Copy link
Member

@lukaszlenart lukaszlenart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@@ -343,6 +360,14 @@ public Map<String, Pojo> getPublicPojoMapDepthTwo() {
}
}

class Pojo {
static class ModelAction implements ModelDriven<Pojo> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one more case where ModelDriven<Object> is used and then getModel() can return conditional model, either a List<Pojo> or Pojo itself. See that example

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah interesting, let me test this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in such cases, the app developer should manually OGNL allowlist any required types, I'm not confident of a secure way to auto allowlist in this case

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it can be tricky, but having such a note should be enough 👍

@kusalk kusalk force-pushed the fix/WW-5468-modeldriven-2 branch from 9a5080d to f6c17e9 Compare October 14, 2024 07:52
Copy link

@kusalk kusalk merged commit 762a0e0 into release/struts-7-0-x Oct 14, 2024
5 checks passed
@kusalk kusalk deleted the fix/WW-5468-modeldriven-2 branch October 14, 2024 07:59
kusalk added a commit that referenced this pull request Nov 1, 2024
WW-5468 Exempt ModelDriven Actions from @StrutsParameter requirement
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants