You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "ASF GitHub Bot (Jira)" <ji...@apache.org> on 2026/10/15 16:57:00 UTC
[jira] [Work logged] (WW-5765) ExecuteAndWaitInterceptor re-stores the transaction token from request parameters instead of the token validated in the request
[ https://issues.apache.org/jira/browse/WW-5765?focusedWorklogId=1047655&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1047655 ]
ASF GitHub Bot logged work on WW-5765:
--------------------------------------
Author: ASF GitHub Bot
Created on: 15/Oct/26 16:56
Start Date: 15/Oct/26 16:56
Worklog Time Spent: 10m
Work Description: lukaszlenart opened a new pull request, #2022:
URL: https://github.com/apache/struts/pull/2022
Fixes [WW-5765](https://issues.apache.org/jira/browse/WW-5765)
### Problem
`ExecuteAndWaitInterceptor` puts a transaction token back into the session every time it returns the wait result, so that an action combining `token` and `execAndWait` keeps accepting its wait-page refreshes after `TokenInterceptor` has consumed the token (WW-1741). It took the value from the `token` request parameter and the name from `struts.token.name`, and did so whether or not a token had been validated in the current request, including for `execAndWait` actions with no token check, such as one using `executeAndWaitStack`. The value and the name were also read under different names.
### Approach
- `TokenHelper.validToken()` records the token name and value it accepted in the current `ActionContext`.
- The new `TokenHelper.restoreValidatedToken()` puts exactly that pair back into the session, and does nothing when no token was validated in the current request.
- `ExecuteAndWaitInterceptor` calls it instead of reading request parameters.
### Behaviour change
A token is now re-stored only if it went through `TokenHelper.validToken()` earlier in the same request. Setups where that never happened, such as a token interceptor ordered after `execAndWait` or custom token checking that bypasses `TokenHelper`, no longer get a token re-stored on the wait result. Worth a line in the migration notes.
### Tests
- `ExecuteAndWaitInterceptorTest`
- an `execAndWait` action without a token interceptor returns `wait` and leaves the session token store unchanged, for the default and a custom token name; this fails on the previous code;
- `token` + `execAndWait` and `tokenSession` + `execAndWait` keep accepting the wait-page refresh that carries the validated token, then consume it on completion.
- `TokenHelperTest`: the validated token is restored; a rejected or unvalidated token leaves the session unchanged.
- `./mvnw -pl core test`: 3472 tests, 0 failures, 0 errors.
A matching PR targets `support/struts-6-x-x`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Issue Time Tracking
-------------------
Worklog Id: (was: 1047655)
Remaining Estimate: 0h
Time Spent: 10m
> ExecuteAndWaitInterceptor re-stores the transaction token from request parameters instead of the token validated in the request
> -------------------------------------------------------------------------------------------------------------------------------
>
> Key: WW-5765
> URL: https://issues.apache.org/jira/browse/WW-5765
> Project: Struts 2
> Issue Type: Bug
> Components: Core Interceptors
> Reporter: Lukasz Lenart
> Priority: Major
> Fix For: 6.13.0, 7.5.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> {{ExecuteAndWaitInterceptor}} puts a transaction token back into the session every time it returns the wait result. It reads the {{token}} request parameter as the value and the {{struts.token.name}} request parameter as the name, and passes both to {{TokenHelper.setSessionToken(...)}}.
> This was added in WW-1741 so that an action using both {{token}} and {{execAndWait}} keeps accepting its wait-page refreshes after {{TokenInterceptor}} has consumed the token. The interceptor does not check that a token was validated in the current request, though, so it stores whatever name and value any request supplies, including requests to an execAndWait action that has no token check at all, such as one using the shipped {{executeAndWaitStack}}.
> The session token store is otherwise written only with server-generated values: the token tag calls {{TokenHelper.setToken}}, which generates a random GUID. A later {{TokenHelper.validToken()}} accepts whatever value is in the store, so a value taken from request parameters is treated the same as one the server generated.
> The value and the name are also read inconsistently: the value always comes from the default {{token}} parameter, while the name comes from {{struts.token.name}}.
> h2. Change
> * {{TokenHelper.validToken()}} records the token name and value it accepted in the current {{ActionContext}}.
> * {{ExecuteAndWaitInterceptor}} re-stores only that recorded pair, and stores nothing when no token was validated in the current request.
> * {{ExecuteAndWaitInterceptor}} no longer reads the token from request parameters.
> h2. Tests
> * An execAndWait action without a token interceptor returns the wait result and leaves the session token store unchanged, for any token name supplied in the request.
> * An action using {{token}} and {{execAndWait}} keeps accepting the wait-page refresh that carries the validated token.
> * The same holds with {{tokenSession}} in place of {{token}}.
> Apply the same change on the 6.x line.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)