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

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

                Author: ASF GitHub Bot
            Created on: 07/Nov/26 17:00
            Start Date: 07/Nov/26 17:00
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #2123:
URL: https://github.com/apache/struts/pull/2123

   Backport of [PR #2122](https://github.com/apache/struts/pull/2122) to 
`support/struts-6-x-x` for 6.13.0.
   
   Fixes [WW-5754](https://issues.apache.org/jira/browse/WW-5754)
   
   ## Summary
   - `StrutsResourceIsolationPolicy` accepts cross-site `navigate` requests for 
`HEAD` as well as `GET`, matching the [Fetch Metadata interceptor 
documentation](https://struts.apache.org/core-developers/fetch-metadata-interceptor)
 (`[GET, HEAD]`).
   - Replaces `testValidTopLevelNavigation`, which sent no `Sec-Fetch-Site` 
header and so never reached the navigation branch, with a cross-site GET + HEAD 
navigation test. `testCrossSiteNavigationWithUnsafeMethodRejected` is unchanged.
   
   ## Decision on cross-site POST navigations
   WW-5754 listed two options. This PR takes option 2: cross-site POST 
navigations stay rejected, as introduced by WW-5753.
   
   Accepting `navigate` for any method was rejected because a cross-site POST 
navigation is the classic form-CSRF request, and `navigate` is also sent for 
`<iframe>` targets. Applications receiving SAML/OIDC `form_post` responses or 
payment-gateway returns opt out per action:
   
   ```xml
   <interceptor-ref name="defaultStack">
       <param name="fetchMetadata.disabled">true</param>
   </interceptor-ref>
   ```
   
   This is a behaviour change against 7.4.0 / 6.12.0 and goes into the 7.5.0 
and 6.13.0 Version Notes and Migration Guide.
   
   `exemptedPaths` is not a working alternative yet: it is matched against the 
context path rather than the request path, so it cannot exempt a single action. 
[WW-5846](https://issues.apache.org/jira/browse/WW-5846), also targeted at 
7.5.0 / 6.13.0, makes it match the request path (servlet path plus path info, 
exact match) in a separate PR. Once both land, the Migration Guide entry offers 
both opt-outs: `exemptedPaths` by path, `fetchMetadata.disabled` per action.
   
   ## Test plan
   - [x] `FetchMetadataInterceptorTest` — HEAD case fails before the change, 
passes after
   - [x] `mvn test -DskipAssembly -pl core` on `support/struts-6-x-x` — 2757 
tests, 0 failures
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   




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

    Worklog Id:     (was: 1053257)
    Time Spent: 0.5h  (was: 20m)

> Fetch Metadata policy rejects cross-site POST and HEAD navigations since 
> WW-5753
> --------------------------------------------------------------------------------
>
>                 Key: WW-5754
>                 URL: https://issues.apache.org/jira/browse/WW-5754
>             Project: Struts 2
>          Issue Type: Bug
>          Components: Core
>            Reporter: Lukasz Lenart
>            Assignee: Lukasz Lenart
>            Priority: Major
>             Fix For: 6.13.0, 7.5.0
>
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> Follow-up to [WW-5753|https://issues.apache.org/jira/browse/WW-5753] (PR 
> [#1983|https://github.com/apache/struts/pull/1983]).
> After WW-5753, {{StrutsResourceIsolationPolicy.isAllowedTopLevelNavigation}} 
> accepts a cross-site request only when {{Sec-Fetch-Mode}} is {{navigate}} 
> *and* the method is {{GET}}. {{FetchMetadataInterceptor}} is part of 
> {{defaultStack}}, so with the default configuration the following now get a 
> 403. Every release since 6.0.0 accepted them:
> * Cross-site POST navigations, for example a SAML or OIDC {{form_post}} 
> response to an action, or a payment gateway posting the user back to the 
> application.
> * Cross-site {{HEAD}} navigations. The [Fetch Metadata interceptor 
> documentation|https://struts.apache.org/core-developers/fetch-metadata-interceptor]
>  lists {{HEAD}} alongside {{GET}} as an accepted method.
> The only way out today is {{exemptedPaths}}. It is matched against 
> {{request.getContextPath()}} ({{FetchMetadataInterceptor}}), so any entry 
> exempts the whole web application, not a single action.
> h2. Options
> # Accept a cross-site request when {{Sec-Fetch-Mode}} is {{navigate}}, 
> whatever the method, as long as the destination is not {{object}} or 
> {{embed}}. Cross-site subresource requests stay rejected, and form-post and 
> redirect-back flows keep working.
> # Keep the GET-only rule, add {{HEAD}}, and document the change as breaking 
> in the 7.5.0 Version Notes and the Migration Guide, with a supported way to 
> exempt individual actions.
> h2. Also
> * Decide whether {{exemptedPaths}} should be matched against the request path 
> (servlet path plus path info) rather than the context path.
> * {{FetchMetadataInterceptorTest.testValidTopLevelNavigation}} sends no 
> {{Sec-Fetch-Site}} header, so it returns at the empty-site check and never 
> reaches the navigation branch. Make it set {{cross-site}}, or drop it in 
> favour of {{testCrossSiteTopLevelGetNavigationAllowed}}.
> * Add tests for a cross-site POST navigation and a cross-site HEAD 
> navigation, asserting whichever behaviour is chosen.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to