This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts-site.git
The following commit(s) were added to refs/heads/main by this push:
new ab95721b00 Document AliasInterceptor's @StrutsParameter authorization
(#347)
ab95721b00 is described below
commit ab95721b00f31b480bf7b1bbfdc75fcce872edc4
Author: ⳕⲛτⲉⲅⲥⲉⳏτⲟⲅ 🕵🏻 <[email protected]>
AuthorDate: Fri Oct 9 10:13:25 2026 +0530
Document AliasInterceptor's @StrutsParameter authorization (#347)
* Document AliasInterceptor's @StrutsParameter authorization
WW-5758 (apache/struts#1991) adds @StrutsParameter authorization to
AliasInterceptor: its
raw-request-parameter fallback follows struts.parameters.requireAnnotations
like the Parameters
Interceptor, and copying a value already resolved on the stack follows the
opt-in
struts.chaining.requireAnnotations like the Chaining Interceptor.
Adds a Parameter Authorization section to the Alias Interceptor page,
mirroring the Chaining
Interceptor page's existing section of the same name, including the
transitionMode note the
review asked for (an alias target is always non-nested, so the same
exemption applies). Adds an
entry for the Alias Interceptor to the @StrutsParameter page's Where
authorization applies list.
Version cited as 7.5.0 to match the pattern of the two prior related fixes
(WW-5752, WW-5753)
and the current pom.xml SNAPSHOT; WW-5758's Fix Version is not yet set, so
this may need updating
once it is.
* Fix factual error, contradictory wording, and review-link typo
Addresses lukaszlenart's review on struts-site#347:
- An alias target CAN be a nested path (an alias map value like 'bean.bar'
is valid - nothing in
AliasInterceptor restricts it, confirmed against the merged code). The
page previously claimed
'always non-nested', which is wrong; transitionMode only exempts the
non-nested case, so a
nested target still needs the annotation regardless of transitionMode.
- Fixed 'always requires... governed by
struts.parameters.requireAnnotations' - contradictory
wording, since with the setting off nothing is required.
- Dropped 'separately-authorized' describing a stack-resolved source value
- it can be any state
an earlier action holds, not necessarily something bound through an
annotated setter.
- Added an 'Upgrading an existing application' note: an app using the
documented foo/bar example
needs bar annotated once struts.parameters.requireAnnotations is enabled,
or the alias is
silently skipped.
* Fix ModelDriven exemption claim and opt-in wording
Addresses lukaszlenart's second review on struts-site#347:
1. The ModelDriven exemption sentence claimed it applies unconditionally,
which isn't true in
defaultStack (alias runs before modelDriven there, so the model isn't on
the stack yet - the
check and the write both land on the action). Reworded to his exact
suggested text: the
exemption only applies in a custom stack that places alias after
modelDriven.
2. 'once struts.parameters.requireAnnotations is enabled' read as opt-in;
it's on by default since
7.0.0. 'silently skipped (logged at WARN)' was self-contradictory.
Reworded to his suggested
text.
---
source/core-developers/alias-interceptor.md | 42 ++++++++++++++++++++++
.../core-developers/struts-parameter-annotation.md | 4 +++
2 files changed, 46 insertions(+)
diff --git a/source/core-developers/alias-interceptor.md
b/source/core-developers/alias-interceptor.md
index 1be9c17c45..6e6b38acdf 100644
--- a/source/core-developers/alias-interceptor.md
+++ b/source/core-developers/alias-interceptor.md
@@ -49,6 +49,48 @@ before `conversionError` so that a conversion failure while
binding the aliased
There is no `overwrite` flag on this interceptor; the ordering above is the
supported way to get that behavior.
+## Parameter Authorization
+
+The value this interceptor copies onto the alias target can come from two
different places, and
+each is authorized differently:
+
+- **The source name does not resolve anywhere on the value stack**, so the
interceptor falls back
+ to the raw HTTP request parameter of that name — the behavior the
`foo`/`bar` example above
+ relies on. This path requires
[`@StrutsParameter`](struts-parameter-annotation.html) on the
+ target when `struts.parameters.requireAnnotations` is enabled (the default
since Struts 7.0.0),
+ the same as the [Parameters Interceptor](parameters-interceptor.html).
+- **The source name resolves on the value stack** — typically a property an
earlier action in a
+ chain already holds. Copying this is the same category of operation as the
+ [Chaining Interceptor](chaining-interceptor.html), so it follows the same
opt-in constant:
+
+ ```xml
+ <constant name="struts.chaining.requireAnnotations" value="true"/>
+ ```
+
+ With this off (the default), a stack-resolved value is copied regardless of
annotation, matching
+ this interceptor's traditional behavior. With it on, an unannotated target
is rejected here too,
+ not just on the request-parameter fallback.
+
+In both cases a rejected target is skipped and logged at `WARN`, and
authorization uses the same
+`ParameterAuthorizer` service the Parameters and Chaining interceptors use.
While an application is
+migrating,
+[`struts.parameters.requireAnnotations.transitionMode=true`](../../security/#defining-and-annotating-your-action-parameters)
+exempts non-nested alias targets, the same way it exempts any other non-nested
setter, on both paths
+above. Nested targets — an alias map value such as `'bean.bar'` is valid —
still need the
+annotation. In a custom stack that places `alias` after `modelDriven`, a
target on the model gets the
+same [`ModelDriven`](struts-parameter-annotation.html#modeldriven-actions)
exemption as the Parameters
+Interceptor.
+
+See also [Where authorization
applies](struts-parameter-annotation.html#where-authorization-applies)
+for an overview of the channels that can populate an action.
+
+### Upgrading an existing application
+
+If an application already uses this interceptor's documented pattern — the
`foo`/`bar` example
+above — `bar` now needs [`@StrutsParameter`](struts-parameter-annotation.html)
for the alias to
+keep working with `struts.parameters.requireAnnotations` enabled (the
default). Without it, the
+alias is skipped and logged at `WARN` instead of setting `bar`.
+
## Extending the Interceptor
This interceptor does not have any known extension points.
diff --git a/source/core-developers/struts-parameter-annotation.md
b/source/core-developers/struts-parameter-annotation.md
index 8617fba2f7..58f34120f1 100644
--- a/source/core-developers/struts-parameter-annotation.md
+++ b/source/core-developers/struts-parameter-annotation.md
@@ -25,6 +25,10 @@ channel that can populate an action from request data:
(default, governed by `struts.parameters.requireAnnotations`).
- [Chaining Interceptor](chaining-interceptor.html) — value-stack copying
during
action chaining (opt-in via `struts.chaining.requireAnnotations`).
+- [Alias Interceptor](alias-interceptor.html) — its raw-request-parameter
fallback follows
+ `struts.parameters.requireAnnotations` like the Parameters Interceptor;
copying a value already
+ resolved on the stack follows `struts.chaining.requireAnnotations` like the
Chaining Interceptor
+ (since Struts 7.5.0 — see [Parameter
Authorization](alias-interceptor.html#parameter-authorization)).
- [Cookie Interceptor](cookie-interceptor.html) — cookie values.
- [JSON](../../plugins/json) and [REST](../../plugins/rest) plugins —
per-property
authorization performed during deserialization, so an unauthorized property
is not set on