Skip to content

WW-5635 Avoid logging sensitive token values in TokenHelper#1738

Merged
lukaszlenart merged 16 commits into
apache:mainfrom
arunmanni-ai:fix/redact-token-values-from-log-output
Jun 14, 2026
Merged

WW-5635 Avoid logging sensitive token values in TokenHelper#1738
lukaszlenart merged 16 commits into
apache:mainfrom
arunmanni-ai:fix/redact-token-values-from-log-output

Conversation

@arunmanni-ai

@arunmanni-ai arunmanni-ai commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

When TokenHelper.validToken() detects a CSRF token mismatch, the WARN-level log message currently includes both the user-submitted form token and the server-side session token in cleartext. Since the session token is only removed on a successful match, the logged value remains a live credential — visible to anyone with access to application logs.

This change keeps the form token in the WARN message (with normalizeSpace() sanitization) and logs full token detail only when devMode is enabled via Dispatcher.getInstance().isDevMode(), consistent with how ParametersInterceptor already handles user-supplied values elsewhere in the codebase.

Changes

TokenHelper.java

  • WARN log keeps the form token with normalizeSpace() sanitization, session token is redacted
  • Full token detail (including session token) is logged at WARN level only when devMode is enabled via Dispatcher, with null guard
  • Dispatcher and normalizeSpace imports added

6 i18n properties files

  • struts-messages.properties, _en, _da, _de, _pl, _pt — updated struts.internal.invalid.token to use {0} (form token only), removed {1} (session token)

What is NOT changed

  • Token generation, entropy, and session storage
  • The equals() comparison and token-removal-on-success logic
  • User-facing error messages (struts.messages.invalid.token — separate key, untouched)
  • Return values from validToken() and interceptor result codes

JIRA: https://issues.apache.org/jira/browse/WW-5635

@lukaszlenart

Copy link
Copy Markdown
Member

Please create a JIRA ticket to cover this change, thank you :)

Comment thread core/src/main/java/org/apache/struts2/util/TokenHelper.java Outdated
Comment thread core/src/main/java/org/apache/struts2/util/TokenHelper.java Outdated
@arunmanni-ai

Copy link
Copy Markdown
Contributor Author

Working on getting ASF JIRA access — will link the ticket once my account is approved.

@arunmanni-ai

Copy link
Copy Markdown
Contributor Author

@lukaszlenart lukaszlenart changed the title Avoid logging sensitive token values in TokenHelper WW-5635 Avoid logging sensitive token values in TokenHelper Jun 14, 2026
@lukaszlenart

Copy link
Copy Markdown
Member

Thanks for the hardening — the production behavior (dropping the session token from the WARN) is the right call, and logging full detail only under devMode is consistent with how ParametersInterceptor already does it.

One blocker though: ActionContext.getContext().isDevMode() won't compile — ActionContext has no isDevMode() method. That accessor lives on Dispatcher, and within a static utility like TokenHelper the way to reach it is Dispatcher.getInstance():

Dispatcher dispatcher = Dispatcher.getInstance();
if (dispatcher != null && dispatcher.isDevMode()) {
    LOG.warn("Token mismatch detail - token name [{}], form token [{}], session token [{}]",
            normalizeSpace(tokenName), normalizeSpace(token), sessionToken);
}

Dispatcher.getInstance() is thread-local-backed and populated during request processing, so it's available here — but keep the null guard since TokenHelper has no DI.

Minor: the PR description says the extra line is DEBUG-level and logs only boolean presence, but the code logs full values at WARN under devMode. The code is fine given the devMode gate — just worth updating the description so it matches the intent.

@arunmanni-ai

Copy link
Copy Markdown
Contributor Author

Updated — using Dispatcher.getInstance().isDevMode() with null guard as you suggested. PR description updated to reflect WARN-level logging under devMode.

@lukaszlenart lukaszlenart enabled auto-merge (squash) June 14, 2026 17:05
@lukaszlenart lukaszlenart merged commit cc3ebc3 into apache:main Jun 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants