Skip to content

WW-5838 Exclude java.beans, java.lang.reflect and java.lang.invoke from OGNL member access by default - #2112

Merged
lukaszlenart merged 1 commit into
support/struts-6-x-xfrom
WW-5838-exclude-java-beans-package-6x
Nov 5, 2026
Merged

lukaszlenart merged 1 commit into
support/struts-6-x-xfrom
WW-5838-exclude-java-beans-package-6x

Conversation

@lukaszlenart

Copy link
Copy Markdown
Member

Fixes WW-5838

6.x counterpart of the main PR.

SecurityMemberAccess compares the declaring class and the target class of each member an OGNL expression resolves against struts.excludedClasses and struts.excludedPackageNames. The shipped lists did not name java.beans. java.beans.Expression and java.beans.Statement perform the call they describe inside the JDK, so the inner call is never presented as a member and neither the excluded-class check nor the static-method check sees it. On this line the exclusion lists are the only layer unless the application enables struts.allowlist.enable, so the package exclusion closes that path.

java.lang.reflect and java.lang.invoke are reachable from an expression only through a static call or a Class object, both already rejected, and are excluded in the same pass. The package rule also covers java.beans.beancontext. An application that needs expression access to a class in one of these packages can re-allow it with struts.excludedPackageExemptClasses.

Changes

  • struts-excluded-classes.xml: the three packages added to struts.excludedPackageNames and struts.devMode.excludedPackageNames
  • StrutsExcludedClassesTest: loads the shipped file with the allowlist disabled and pins that member access on Expression, Statement, Method and MethodHandle is denied (declaring-class and target-class branches), that the dev-mode list carries the same entries (production list overridden to a single entry so only the dev-mode list can deny), that the struts.excludedPackageNames setting replaces the shipped list, and that an Expression constructed inside an OGNL expression is rejected at its constructor. All six tests fail without the XML change.

Full core test suite: 2745 tests, 0 failures.

Reported by Yu Deshui (于得水, @qiushui_sky) and by Daniel Owens.

🤖 Generated with Claude Code

…g.invoke from OGNL member access

SecurityMemberAccess compares the declaring class and the target class of each
member an expression resolves against the exclusion lists. java.beans.Expression
and java.beans.Statement perform the call they describe inside the JDK, so the
inner call is never presented as a member and neither the excluded-class nor the
static-method check sees it. On this line the exclusion lists are the only layer
unless the application enables struts.allowlist.enable, so the package exclusion
closes that path. java.lang.reflect and java.lang.invoke are reachable from an
expression only through a static call or a Class object, both already rejected,
and are excluded in the same pass. An application that needs one of these
classes in an expression can re-allow it with struts.excludedPackageExemptClasses.

StrutsExcludedClassesTest pins the shipped lists with the allowlist disabled:
member access on Expression, Statement, Method and MethodHandle is denied, the
dev-mode list agrees, and an Expression constructed inside an OGNL expression is
rejected at its constructor.

Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
@lukaszlenart
lukaszlenart marked this pull request as ready for review November 5, 2026 14:24
@sonarqubecloud

sonarqubecloud Bot commented Nov 5, 2026

Copy link
Copy Markdown

@lukaszlenart
lukaszlenart merged commit 5e49ebe into support/struts-6-x-x Nov 5, 2026
10 checks passed
@lukaszlenart
lukaszlenart deleted the WW-5838-exclude-java-beans-package-6x branch November 5, 2026 16:00
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.

1 participant