[ 
https://issues.apache.org/jira/browse/WW-5718?focusedWorklogId=1042043&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1042043
 ]

ASF GitHub Bot logged work on WW-5718:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 16/Sep/26 16:38
            Start Date: 16/Sep/26 16:38
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #1957:
URL: https://github.com/apache/struts/pull/1957

   Fixes [WW-5718](https://issues.apache.org/jira/browse/WW-5718)
   
   `restDefaultStack` and `beanValidationDefaultStack` were forked from core's 
`defaultStack` before WW-5083 added `coep`, `coop` and `fetchMetadata` in 6.0.0 
and were never brought back in step, so a package extending `rest-default` or 
`struts-bean-validation` silently lost the COOP/COEP response headers and the 
Fetch Metadata request check.
   
   ### Changes
   
   - The three refs are copied into both stacks with `defaultStack`'s 
parameters, in the same slot: after `conversionError`, ahead of validation. A 
test per plugin loads `struts-default.xml` + `struts-plugin.xml` and pins that 
order.
   - `RestActionInvocation` now honours a bare HTTP status returned as the 
result code. `FetchMetadataInterceptor` rejects a cross-site request by 
returning `"403"` without invoking the action; the REST result path wrapped any 
unknown code in a `DefaultHttpHeaders` whose status defaults to 200, so a 
JSON/XML client received **200** — for a GET, with the unexecuted model 
serialised. Such a code now sets the status and drops the representation; a 
mapped `403` result still executes as before.
   
   ### Migration note
   
   This is a behaviour change for existing REST and Bean Validation 
deployments. `fetchMetadata` rejects requests whose `Sec-Fetch-Site` marks them 
cross-site (other than top-level navigations), so a REST API deliberately 
serving cross-origin browser clients will answer them with 403 unless it sets 
`fetchMetadata.exemptedPaths` or `fetchMetadata.disabled=true` on the stack 
ref. To be called out in the Version Notes; the same change is due on 
`support/struts-6-x-x` (fix version 6.12.0).
   
   ### Observed, left out
   
   - `csp` (2020) and `httpMethod` (2014) are absent from both plugin stacks 
for the same reason; `datetime`/`multiselect` from `restDefaultStack` too. Not 
in this ticket's scope.
   - `JacksonXmlHandler.fromObject` and `JuneauXmlHandler.fromObject` 
dereference `obj.getClass()` and NPE on a `null` target (`XStreamHandler` 
guards it). Pre-existing on `main` for every XML POST/PUT/DELETE under the 
default `restrictToGet=true`; a rejected cross-site XML GET now reaches the 
same path. Separate ticket.
   - On the HTML path a `403` code without a mapped result still ends in 
`ConfigurationException("No result defined …")`, exactly as in core's 
`DefaultActionInvocation`.
   
   ### Testing
   
   `mvn test -DskipAssembly -pl plugins/rest,plugins/bean-validation` — green 
(286 + 17 tests).
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   




Issue Time Tracking
-------------------

            Worklog Id:     (was: 1042043)
    Remaining Estimate: 0h
            Time Spent: 10m

> Plugin-provided default interceptor stacks omit the resource-isolation 
> interceptors
> -----------------------------------------------------------------------------------
>
>                 Key: WW-5718
>                 URL: https://issues.apache.org/jira/browse/WW-5718
>             Project: Struts 2
>          Issue Type: Improvement
>          Components: Core Interceptors, Plugin - Bean Validation, Plugin - 
> REST
>            Reporter: Lukasz Lenart
>            Priority: Major
>             Fix For: 6.12.0, 7.4.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> {{WW-5083}} added the Fetch Metadata resource-isolation interceptor to core's 
> {{defaultStack}} in 6.0.0, alongside {{coop}} and {{coep}}. All three are 
> declared enabled in {{core/src/main/resources/struts-default.xml}}:
> {code}<interceptor-ref name="coep">
>     <param name="disabled">false</param>
>     ...
> <interceptor-ref name="coop">
>     <param name="disabled">false</param>
>     ...
> <interceptor-ref name="fetchMetadata">
>     <param name="disabled">false</param>
> </interceptor-ref>
> {code}
> Two bundled plugins replace {{defaultStack}} wholesale with their own stack 
> and set it as the package default. Both stacks were forked from 
> {{defaultStack}} before {{WW-5083}} and were never updated, so neither 
> carries any of the three interceptors:
> * {{plugins/rest/src/main/resources/struts-plugin.xml}} — 
> {{restDefaultStack}}, installed via {{<default-interceptor-ref 
> name="restDefaultStack"/>}}
> * {{plugins/bean-validation/src/main/resources/struts-plugin.xml}} — 
> {{beanValidationDefaultStack}}, installed via {{<default-interceptor-ref 
> name="beanValidationDefaultStack"/>}}
> The result is that an action package extending {{rest-default}} or 
> {{bean-validation-default}} silently loses the cross-origin request filtering 
> and the COOP/COEP response headers that an otherwise identical 
> {{struts-default}} package gets by default. Nothing in the configuration 
> signals the difference, and the omission is not the outcome of a decision 
> recorded anywhere — the interceptors simply post-date the forks.
> {{config-browser}}'s {{configBrowserDefault}} delegates to 
> {{validationWorkflowStack}}, which derives from {{defaultStack}}, so it is 
> unaffected.
> h3. Proposed change
> Add {{coep}}, {{coop}} and {{fetchMetadata}} to {{restDefaultStack}} and 
> {{beanValidationDefaultStack}}, with the same parameters {{defaultStack}} 
> uses, positioned as they are in {{defaultStack}}.
> h3. Notes
> * Affects 6.x and 7.x alike: {{WW-5083}} shipped in 6.0.0, and both plugin 
> stacks lack the interceptors on {{main}} and on {{support/struts-6-x-x}}.
> * This is a behaviour change for existing REST and Bean Validation 
> deployments: {{fetchMetadata}} rejects requests whose {{Sec-Fetch-Site}} 
> marks them cross-site, so a REST API deliberately serving cross-origin 
> browser clients will start seeing 403s unless it configures {{exemptedPaths}} 
> or disables the interceptor. It should be called out in the migration notes.
> * The wider point is structural: a plugin that replaces {{defaultStack}} 
> inherits nothing from it afterwards, so every future addition to 
> {{defaultStack}} has to be mirrored by hand into each fork. Worth considering 
> whether these stacks can extend the core stack rather than restate it.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to