@@ -88,6 +88,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
8888
8989 protected boolean ordered = false ;
9090 protected boolean requireAnnotations = false ;
91+ protected boolean requireAnnotationsTransitionMode = false ;
9192
9293 private ValueStackFactory valueStackFactory ;
9394 protected ThreadAllowlist threadAllowlist ;
@@ -116,6 +117,20 @@ public void setRequireAnnotations(String requireAnnotations) {
116117 this .requireAnnotations = BooleanUtils .toBoolean (requireAnnotations );
117118 }
118119
120+ /**
121+ * When 'Transition Mode' is enabled, parameters that are not 'nested' will be accepted without annotations. What
122+ * this means in practice is that all public setters on an Action will be exposed for parameter injection again, and
123+ * only 'nested' parameters, i.e. public getters on an Action, will require annotations.
124+ * <p>
125+ * In this mode, the OGNL auto-allowlisting capability is not degraded in any way, and as such, it offers a
126+ * convenient option for applications to enable the OGNL allowlist capability whilst they work through the process
127+ * of annotating all their Action parameters.
128+ */
129+ @ Inject (value = StrutsConstants .STRUTS_PARAMETERS_REQUIRE_ANNOTATIONS_TRANSITION , required = false )
130+ public void setRequireAnnotationsTransitionMode (String transitionMode ) {
131+ this .requireAnnotationsTransitionMode = BooleanUtils .toBoolean (transitionMode );
132+ }
133+
119134 @ Inject
120135 public void setExcludedPatterns (ExcludedPatternsChecker excludedPatterns ) {
121136 this .excludedPatterns = excludedPatterns ;
@@ -343,9 +358,13 @@ protected boolean isParameterAnnotatedAndAllowlist(String name, Object action) {
343358 return true ;
344359 }
345360
361+ long paramDepth = name .codePoints ().mapToObj (c -> (char ) c ).filter (NESTING_CHARS ::contains ).count ();
362+ if (requireAnnotationsTransitionMode && paramDepth == 0 ) {
363+ return true ;
364+ }
365+
346366 int nestingIndex = indexOfAny (name , NESTING_CHARS_STR );
347367 String rootProperty = nestingIndex == -1 ? name : name .substring (0 , nestingIndex );
348- long paramDepth = name .codePoints ().mapToObj (c -> (char ) c ).filter (NESTING_CHARS ::contains ).count ();
349368
350369 return hasValidAnnotatedMember (rootProperty , action , paramDepth );
351370 }
0 commit comments