Commit Graph

8318 Commits

Author SHA1 Message Date
Lukasz Lenart 789dbf3cd2 WW-5640 Add WebJars support to Struts core (#1765)
* WW-5640 docs: design for WebJars support in Struts core

Adds first-class WebJars support so client-side libraries can be
referenced by a version-less logical path and served through the
existing static-content pipeline. Grounded against 7.2.x source.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 docs: implementation plan for WebJars support

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 build: add webjars-locator-lite dependency

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 feat: add webjars config constants and defaults

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 docs: correct plan test framework to JUnit 4

core uses JUnit 4 + AssertJ + Mockito, not JUnit 5 Jupiter (no
Jupiter engine on the classpath). Test tasks translate accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 feat: add WebJarUrlProvider resolution seam

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 feat: register WebJarUrlProvider bean

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 feat: extend static content-type map for webjar assets

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 feat: serve webjar assets via static content loader

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 feat: add <s:webjar> tag and <@s.webjar> macro

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 docs: add generated tag reference for <s:webjar>

Annotation-processor-generated tag reference (attributes + description),
tracked like every other tag's docs under core/src/site/resources/tags/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 fix: address final review (log level, resolveUrl traversal test, javadoc)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5640 refactor: address SonarCloud code smells

- getContentType: replace long if/else chain with a static extension->
  MIME map (S3776 cognitive complexity)
- DefaultWebJarUrlProvider.split: return Optional<String[]> instead of a
  null sentinel (S1168; Optional fits the reject semantics, empty-array
  would not)
- serving tests: rename local 'loader' -> 'webJarLoader' to stop hiding
  the ContentTypeProbe field (S1117)
- WebJarTest: use assertThat(writer).hasToString(...) (S5838)

S110 (WebJarTag inheritance depth) is inherent to the Struts tag base
class hierarchy shared by every tag; left as-is.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 15:03:05 +02:00
dependabot[bot] a09f2a93af build(deps): bump github/codeql-action/upload-sarif (#1758)
Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from eda5730a8bfb740e03a28087a958444c646e5842 to 628fc3f124e68b0151f0d2a5d81e864ee1e42335.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/eda5730a8bfb740e03a28087a958444c646e5842...628fc3f124e68b0151f0d2a5d81e864ee1e42335)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 628fc3f124e68b0151f0d2a5d81e864ee1e42335
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-01 12:57:29 +02:00
dependabot[bot] 29f75f2dc0 build(deps): bump org.htmlunit:htmlunit from 5.1.0 to 5.2.0 (#1762)
Bumps [org.htmlunit:htmlunit](https://github.com/HtmlUnit/htmlunit) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/HtmlUnit/htmlunit/releases)
- [Commits](https://github.com/HtmlUnit/htmlunit/compare/5.1.0...5.2.0)

---
updated-dependencies:
- dependency-name: org.htmlunit:htmlunit
  dependency-version: 5.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-01 12:57:04 +02:00
Jarek Potiuk dc90e48909 Add draft security threat model (THREAT_MODEL.md) + discoverability pointer (#1756)
* Add draft security threat model (THREAT_MODEL.md)

Generated-by: Claude Opus 4.8 (1M context)

* SECURITY.md: link to THREAT_MODEL.md for scanner/triager discoverability

Generated-by: Claude Opus 4.8 (1M context)

* Fix dangling §14 refs and tighten provenance in threat model

Address code-review findings on the THREAT_MODEL.md draft:

- Add the missing §14 Q-env and Q-egress open questions, so every
  *(inferred)* claim that cites them now resolves (restores the
  "each inferred claim has a matching §14 question" invariant).
- Tag the two previously bare *(inferred)* claims (examples/showcase,
  on-path attacker) with their matching question IDs.
- Soften the §1 header: drop the ASF Security team / PMC authorship
  attribution on an unratified draft; state it is drafted for PMC review.
- Correct the OGNL Java Security Manager wording: SecurityManager is
  deprecated for removal since JDK 17 and permanently disabled in JDK 24,
  not simply "does not work on JDK 21+".
- AGENTS.md: point the Assess step at THREAT_MODEL.md's disposition guide
  so the triage wrapper links the model directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Lukasz Lenart <lukaszlenart@apache.org>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 21:10:42 +02:00
Lukasz Lenart 50c16e93b1 Release 7.2.1-RC1 (#1744)
* [maven-release-plugin] prepare release STRUTS_7_2_1

* [maven-release-plugin] prepare for next development iteration
2026-06-26 07:18:26 +02:00
dependabot[bot] 07afccbb2f build(deps): bump actions/checkout from 6 to 7 (#1755)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 07:18:09 +02:00
dependabot[bot] 153e42bb9b build(deps): bump org.glassfish.jaxb:jaxb-bom from 4.0.8 to 4.0.9 (#1753)
Bumps org.glassfish.jaxb:jaxb-bom from 4.0.8 to 4.0.9.

---
updated-dependencies:
- dependency-name: org.glassfish.jaxb:jaxb-bom
  dependency-version: 4.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 07:17:43 +02:00
dependabot[bot] 46ba90f797 build(deps-dev): bump org.jacoco:jacoco-maven-plugin (#1751)
Bumps [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.14 to 0.8.15.
- [Release notes](https://github.com/jacoco/jacoco/releases)
- [Commits](https://github.com/jacoco/jacoco/compare/v0.8.14...v0.8.15)

---
updated-dependencies:
- dependency-name: org.jacoco:jacoco-maven-plugin
  dependency-version: 0.8.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 07:17:30 +02:00
dependabot[bot] 22243e75f5 build(deps): bump org.sitemesh:sitemesh from 3.2.2 to 3.2.3 (#1749)
Bumps [org.sitemesh:sitemesh](https://github.com/sitemesh/sitemesh3) from 3.2.2 to 3.2.3.
- [Release notes](https://github.com/sitemesh/sitemesh3/releases)
- [Commits](https://github.com/sitemesh/sitemesh3/compare/3.2.2...3.2.3)

---
updated-dependencies:
- dependency-name: org.sitemesh:sitemesh
  dependency-version: 3.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 07:17:04 +02:00
dependabot[bot] 1e3fa9a2d7 build(deps-dev): bump byte-buddy.version from 1.18.8 to 1.18.10 (#1745)
Bumps `byte-buddy.version` from 1.18.8 to 1.18.10.

Updates `net.bytebuddy:byte-buddy` from 1.18.8 to 1.18.10
- [Release notes](https://github.com/raphw/byte-buddy/releases)
- [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md)
- [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.8...byte-buddy-1.18.10)

Updates `net.bytebuddy:byte-buddy-agent` from 1.18.8 to 1.18.10
- [Release notes](https://github.com/raphw/byte-buddy/releases)
- [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md)
- [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.8...byte-buddy-1.18.10)

---
updated-dependencies:
- dependency-name: net.bytebuddy:byte-buddy
  dependency-version: 1.18.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
- dependency-name: net.bytebuddy:byte-buddy-agent
  dependency-version: 1.18.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 07:16:26 +02:00
Lukasz Lenart 01a561d9d8 Add CONTRIBUTING.md for new contributors (#1757) 2026-06-25 19:43:45 +00:00
Lukasz Lenart 59e342488d WW-5256 Decouple FreeMarker whitespace stripping from devMode (#1743)
* WW-5256 docs: design to decouple FreeMarker whitespace stripping from devMode

Fixes s:textarea rendering blank lines and HTML whitespace bloat in devMode
by honoring struts.freemarker.whitespaceStripping unconditionally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5256 docs: implementation plan to decouple whitespace stripping from devMode

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5256 test: prove whitespace stripping wrongly disabled in devMode

* WW-5256 fix(freemarker): honor whitespaceStripping regardless of devMode

* WW-5256 docs: drop devMode note from whitespaceStripping constant

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 12:22:51 +02:00
Lukasz Lenart 489445c78d Release 7.2.0-RC1 (#1742)
* [maven-release-plugin] prepare release STRUTS_7_2_0

* [maven-release-plugin] prepare for next development iteration
2026-06-15 12:07:02 +02:00
Arun cc3ebc3c1f WW-5635 Avoid logging sensitive token values in TokenHelper (#1738)
* Avoid logging sensitive token values in TokenHelper

Redact form and session token values from WARN-level log output
in TokenHelper.validToken() and update corresponding i18n message
properties. Detailed diagnostics moved to DEBUG level with
sanitized input.

* Update struts-messages.properties

* Update invalid token error message for clarity

* Update struts-messages_da.properties

* Update struts-messages_de.properties

* Update Polish translation for invalid token message

* Update invalid token message in Portuguese properties

* Improve token mismatch warning logging

Updated warning message to include the form token in the log.

* Update struts-messages.properties

* Update invalid token message format in properties file

* Update invalid token message for clarity

* Update struts-messages_de.properties

* Update struts-messages_pl.properties

* Update invalid token message format in properties file

* Update TokenHelper.java

* Refactor token mismatch logging for development mode
2026-06-14 17:08:39 +00:00
Arun 8f9b4b8a90 WW-5636 Harden redirect URL escaping in non-302 response body (#1737)
* Implement test for status code 200 with HTML escaping

* Escape HTML in ServletRedirectResult response

Escape HTML in the final location before writing to the response.
2026-06-14 18:44:43 +02:00
Lukasz Lenart dd830dca80 WW-5630 test: streamline ConfigParseUtilTest and convert to JUnit 4 (#1740)
Collapse 12 overlapping cache tests to 5 focused ones, replace the
~80-entry JDK class-name literal with a synthetic-name loop bounded by
the inner-cache limit, and drop reflection from the behavioral tests
(load-count assertions only). Reflection is retained solely in the two
size-bound tests, where Caffeine exposes no public seam.

Production ConfigParseUtil caching logic is unchanged.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 09:16:39 +00:00
dependabot[bot] 289bcaa922 build(deps): bump org.htmlunit:htmlunit from 4.21.0 to 5.1.0 (#1733)
Bumps [org.htmlunit:htmlunit](https://github.com/HtmlUnit/htmlunit) from 4.21.0 to 5.1.0.
- [Release notes](https://github.com/HtmlUnit/htmlunit/releases)
- [Commits](https://github.com/HtmlUnit/htmlunit/compare/4.21.0...5.1.0)

---
updated-dependencies:
- dependency-name: org.htmlunit:htmlunit
  dependency-version: 5.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-13 08:34:36 +02:00
dependabot[bot] b808dcb845 build(deps): bump com.fasterxml.jackson:jackson-bom (#1729)
Bumps [com.fasterxml.jackson:jackson-bom](https://github.com/FasterXML/jackson-bom) from 2.21.3 to 2.22.0.
- [Commits](https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.21.3...jackson-bom-2.22.0)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson:jackson-bom
  dependency-version: 2.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-13 08:33:28 +02:00
Lukasz Lenart 4f3fd69aa6 WW-5632 Harden commons-fileupload2 dependency against milestone binary-incompatibility (#1735)
* WW-5632 docs: add commons-fileupload2 milestone-hardening design spec

Design for hardening the commons-fileupload2 dependency against
milestone binary-incompatibility (manage -core, activate a scoped
enforcer rule, add a runtime API guard in AbstractMultiPartRequest).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5632 docs: add implementation plan for fileupload2 milestone hardening

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5632 build(deps): manage commons-fileupload2-core alongside jakarta-servlet6

Pin both commons-fileupload2 artifacts to a single
commons-fileupload2.version property so the volatile -core API can no
longer skew from -jakarta-servlet6 in the reactor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5632 build: enforce a single commons-fileupload2 version

Activate maven-enforcer-plugin (previously dormant in pluginManagement)
with a fileupload-scoped bannedDependencies rule so any divergent
commons-fileupload2 version fails the build early.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5632 fix(fileupload): fail fast on incompatible commons-fileupload2 API

Verify once per JVM that the fileupload size-limit setters exist and
throw a clear StrutsException reporting the core/jakarta version skew,
replacing an opaque deep-stack NoSuchMethodError in downstream runtimes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* WW-5632 fix(fileupload): make API-verification guard static

Resolve Sonar java:S2696 (instance method writing a static field) by
making ensureFileUploadApiVerified() static; verification is JVM-global.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 08:28:47 +02:00
brianandle 210dc86b88 WW-5630 - Performance Issue SecurityMemberAccess (#1721)
* WW-5630 - Performance Issue SecurityMemberAccess
* Add size bound cache, 50, for Class lookup
* Add unit test

Code generated by Copilot

* WW-5630 - Add additional UT

* WW-5630 - Add UT for non-existent class

* WW-5630 - Review feedback changes
* Cache ClassLoader directly
* Use weakKeys and weakValues
* Comment on the ClassLookupException
* Additional Unit Tests

Assistance in coding using co-pilot

* WW-5630 - Additional review
* Limit outer, Classloader, to 25. Ensure memory bounding.
* Limit inner, Classes, to 50. Ensure memory bounding.
* Additional UTs

With co-pilot assitance
2026-06-12 17:12:26 +00:00
dependabot[bot] 7c6034c667 build(deps-dev): bump org.apache.maven.plugins:maven-failsafe-plugin (#1732)
Bumps [org.apache.maven.plugins:maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.5.5 to 3.5.6.
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.5...surefire-3.5.6)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-failsafe-plugin
  dependency-version: 3.5.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-10 13:23:50 +02:00
dependabot[bot] 5e725a72cd build(deps): bump github/codeql-action from 4.36.0 to 4.36.2 (#1734)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.0 to 4.36.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v4.36.0...v4.36.2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-10 13:23:21 +02:00
dependabot[bot] 53ef1ad883 build(deps): bump org.apache.maven.plugins:maven-dependency-plugin (#1730)
Bumps [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.10.0 to 3.11.0.
- [Release notes](https://github.com/apache/maven-dependency-plugin/releases)
- [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.10.0...maven-dependency-plugin-3.11.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-dependency-plugin
  dependency-version: 3.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-10 13:22:50 +02:00
dependabot[bot] 0972a608a3 build(deps): bump maven-surefire-plugin.version from 3.5.5 to 3.5.6 (#1731)
Bumps `maven-surefire-plugin.version` from 3.5.5 to 3.5.6.

Updates `org.apache.maven.surefire:surefire-junit47` from 3.5.5 to 3.5.6

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.5 to 3.5.6
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.5...surefire-3.5.6)

---
updated-dependencies:
- dependency-name: org.apache.maven.surefire:surefire-junit47
  dependency-version: 3.5.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-version: 3.5.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-10 13:22:32 +02:00
Lukasz Lenart 9011c32b38 WW-5631 Add opt-in @StrutsParameter enforcement to ChainingInterceptor (#1719)
* WW-5631 feat(chaining): add struts.chaining.requireAnnotations constant

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 feat(chaining): default struts.chaining.requireAnnotations=false

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 test(chaining): add annotated/unannotated chaining fixtures

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 test(chaining): add failing @StrutsParameter enforcement tests

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 feat(chaining): enforce @StrutsParameter on target when opted in

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 refactor(chaining): align requireAnnotations parsing with BooleanUtils

Use BooleanUtils.toBoolean for the chaining requireAnnotations flag so it
accepts the same values (yes/on/1) as the sibling
struts.parameters.requireAnnotations switch, and unify the enforcement WARN
message prefix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 test(chaining): cover includes interaction and proxied target

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 docs(chaining): document struts.chaining.requireAnnotations

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 test(chaining): cover fail-closed introspection; clarify target==action

Add a test asserting nothing is copied when the target action cannot be
introspected (fail-closed), and document why isAuthorized is called with
target == action for chaining (no ModelDriven exemption).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5631 fix(chaining): address SonarCloud findings

- Mark injected parameterAuthorizer/ognlUtil fields transient (S1948);
  they are re-injected by the container, not serialized.
- Extract per-object copy into copyObjectToAction so the copyStack loop
  uses no break/continue (S135); fail-closed path now returns from the
  helper instead of continuing the loop.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 13:19:43 +02:00
Lukasz Lenart 69cb2964f0 docs(skills): add triaging-security-reports skill (#1722)
Add an agent skill for triaging privately-disclosed security reports:
research each claim from source without trusting the reporter, verify
effective runtime defaults (config overrides field initializers), avoid
introducing unverified facts into responses, and frame findings as
vulnerability vs. operator responsibility.

Developed test-first: a baseline run produced contradictory, unverified
claims about defaults; the skill closes that gap and was verified to also
avoid over-correcting into reflexive rejection of valid reports.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 08:44:18 +02:00
dependabot[bot] e637bb16a3 build(deps): bump asm.version from 9.10 to 9.10.1 (#1713)
Bumps `asm.version` from 9.10 to 9.10.1.

Updates `org.ow2.asm:asm` from 9.10 to 9.10.1

Updates `org.ow2.asm:asm-commons` from 9.10 to 9.10.1

---
updated-dependencies:
- dependency-name: org.ow2.asm:asm
  dependency-version: 9.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.ow2.asm:asm-commons
  dependency-version: 9.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-28 07:17:30 +02:00
dependabot[bot] 1555cabff1 build(deps): bump org.apache.maven.plugins:maven-site-plugin (#1711)
Bumps [org.apache.maven.plugins:maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.21.0 to 3.22.0.
- [Release notes](https://github.com/apache/maven-site-plugin/releases)
- [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.21.0...maven-site-plugin-3.22.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-site-plugin
  dependency-version: 3.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-28 07:17:16 +02:00
dependabot[bot] c7b1ca3f0a build(deps): bump github/codeql-action from 4.35.5 to 4.36.0 (#1710)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.5 to 4.36.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v4.35.5...v4.36.0)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-28 07:16:52 +02:00
Lukasz Lenart 26756ce85c security(versions): updates list of supported versions (#1708) 2026-05-22 04:47:05 +00:00
dependabot[bot] d628d949a0 build(deps): bump org.apache.logging.log4j:log4j-bom (#1685)
Bumps [org.apache.logging.log4j:log4j-bom](https://github.com/apache/logging-log4j2) from 2.25.4 to 2.26.0.
- [Release notes](https://github.com/apache/logging-log4j2/releases)
- [Changelog](https://github.com/apache/logging-log4j2/blob/2.x/RELEASE-NOTES.adoc)
- [Commits](https://github.com/apache/logging-log4j2/compare/rel/2.25.4...rel/2.26.0)

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-bom
  dependency-version: 2.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 10:06:49 +02:00
dependabot[bot] cc6b4cfd6e build(deps): bump asm.version from 9.9.1 to 9.10 (#1695)
Bumps `asm.version` from 9.9.1 to 9.10.

Updates `org.ow2.asm:asm` from 9.9.1 to 9.10

Updates `org.ow2.asm:asm-commons` from 9.9.1 to 9.10

---
updated-dependencies:
- dependency-name: org.ow2.asm:asm
  dependency-version: '9.10'
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.ow2.asm:asm-commons
  dependency-version: '9.10'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 09:18:23 +02:00
Lukasz Lenart f26325ff90 ci(dependabot): fix cooldown property name (#1702)
The `cooldown` block expects `default-days`, not `default`. Using the
wrong key fails schema validation, causing Dependabot to silently fall
back to the previously valid config — which still targets
`release/struts-6-8-x` instead of `support/struts-6-x-x`.

Also adds a 3-day cooldown to the `main` maven entry for consistency.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 07:07:05 +00:00
dependabot[bot] 1bd2951f7e build(deps-dev): bump org.apache.maven.plugins:maven-enforcer-plugin (#1698)
Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/apache/maven-enforcer/releases)
- [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.6.2...enforcer-3.6.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-enforcer-plugin
  dependency-version: 3.6.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 08:59:25 +02:00
dependabot[bot] 16618e0236 build(deps): bump github/codeql-action from 4.35.4 to 4.35.5 (#1694)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.4 to 4.35.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v4.35.4...v4.35.5)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 08:58:58 +02:00
Lukasz Lenart 419fb1f5c6 WW-5535 test(core): cover wildcard-resolved unannotated methods via real proxy (#1692)
Closes the test gap noted in the WW-5535 research: no integration test
exercised HttpMethodInterceptor against a real DefaultActionProxy resolving
a wildcard action with an unannotated method.

Uses xwork-test-allowed-methods.xml's existing <action name="Wild-*"
method="{1}"> on HttpMethodsTestAction. URL "Wild-execute" resolves to
ActionSupport.execute() (no method-level HTTP annotation); the class-level
@AllowedHttpMethod(POST) must still reject GET end-to-end.

Together with the prior MockActionProxy regression tests, this locks in
both halves of the fix:
- DefaultActionProxy.resolveMethod() sets isMethodSpecified()=true for
  wildcard-resolved methods (WW-5535 / #1592)
- HttpMethodInterceptor falls back to class-level annotations when the
  resolved method is unannotated (#1690)
2026-05-19 08:26:49 +00:00
ⳕⲛτⲉⲅⲥⲉⳏτⲟⲅ 🕵🏻 213b83f64f fix(core): enforce class-level HTTP method annotations for wildcard-resolved unannotated methods (#1690)
The WW-5535 fix (commit 4d2eb93) corrected isMethodSpecified() for wildcard-resolved
methods but introduced a structural gap in HttpMethodInterceptor.intercept().

The if/else-if structure made the class-level annotation check unreachable whenever
isMethodSpecified()=true and the resolved method carries no method-level annotation:

  if (isMethodSpecified()) {
      if (isAnnotatedBy(method)) { ... }
      // falls through silently
  } else if (isAnnotatedBy(class)) { ... }  // never reached
  return invocation.invoke();               // no enforcement

Fix: convert else-if to standalone if so the class-level check is always evaluated
as a fallback when the method itself has no annotation. Method-level annotations
still take precedence (checked first).

Add two regression tests covering the wildcard-resolved unannotated method scenario.

Co-authored-by: g0w6y <g0w6y@users.noreply.github.com>
2026-05-19 08:05:21 +02:00
Lukasz Lenart 7ea7911cf8 chore(rat): excludes Markdown files in docs/ folder (#1691) 2026-05-18 13:04:58 +00:00
Lukasz Lenart e83487f0e1 WW-5627 Gate CookieInterceptor through ParameterAuthorizer (#1681)
* WW-5627 add ParameterAllowlister interface and STRUTS_PARAMETER_ALLOWLISTER constant

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WW-5627 add OgnlParameterAllowlister default implementation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WW-5627 register ParameterAllowlister bean in struts-default DI

* WW-5627 delegate ParametersInterceptor OGNL allowlisting to OgnlParameterAllowlister

Also register ParameterAllowlister in DefaultConfiguration bootstrap
factories so it is available in test containers (parallel to how
ParameterAuthorizer was already registered there).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WW-5627 test(cookie): failing test for unannotated setter skip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WW-5627 gate CookieInterceptor cookie injection through ParameterAuthorizer

Adds a 5-arg `populateCookieValueIntoStack(name, value, map, stack, action)` hook
that runs cookie writes through `ParameterAuthorizer.isAuthorized` and primes
`ThreadAllowlist` via `ParameterAllowlister` for nested paths, then delegates
to the legacy 4-arg form. The 4-arg form is `@Deprecated(since="7.2.0")` but
its body is unchanged, so existing subclass overrides automatically receive
only authorized cookies. Default-config behavior is preserved because the
authorizer short-circuits when `requireAnnotations=false`.

Existing `CookieInterceptorTest` instantiates `new CookieInterceptor()` rather
than going through the container, leaving the new injected fields null. Wires
explicit pass-through lambdas through a `disableAuthorizationGate(...)` helper
so those tests continue to exercise default-config behavior.

* WW-5627 cover CookieInterceptor authorization matrix in CookieInterceptorAnnotationTest

* WW-5627 docs(cookie): document new 5-arg extension hook and deprecation

* WW-5627 wire OgnlParameterAllowlister in StrutsParameterAnnotationTest fixture

* WW-5627 address SonarCloud findings on PR #1681

- S1948: mark transient on the new ParameterAuthorizer/ParameterAllowlister
  fields in CookieInterceptor and ParametersInterceptor (the host classes
  are Serializable; the injected services are not).
- S1874: suppress the deprecation warning on the new 5-arg
  populateCookieValueIntoStack — the delegation to the deprecated 4-arg
  form is the contract that lets existing subclass overrides participate.
- S3776: extract `allowlistViaPropertyDescriptor` and
  `allowlistViaPublicField` from `OgnlParameterAllowlister.allowlistAuthorizedPath`
  to drop cognitive complexity below the threshold.
- S1068: remove the unused `mapping` test fixture field.

* WW-5627 clarify ParameterAllowlister contract and tidy ParametersInterceptor

Rename `ParameterAllowlister#allowlistAuthorizedPath` to `primeAllowlistForPath`
to make the contract explicit: the SAM is a side-effect-only priming hook that
runs after `ParameterAuthorizer#isAuthorized` has already decided. A no-op
return means "no priming needed or possible", never "rejected". The interface
name stays channel-agnostic; only the impl class (`OgnlParameterAllowlister`)
binds the priming to OGNL's `ThreadAllowlist`.

Add a `LOG.debug` in `OgnlParameterAllowlister` for the case where authorization
passed but no `@StrutsParameter` could be located on the root property
(e.g. `ModelDriven` models without per-property annotations) so the
authorize-vs-prime gap is observable instead of surfacing later as an opaque
OGNL traversal failure.

Drop the dead `performOgnlAllowlisting` pass-through and its unused `paramDepth`
parameter from `ParametersInterceptor` — the depth check is already enforced
inside `OgnlParameterAllowlister.primeAllowlistForPath`, so the outer guard was
a redundant computation.

No behavior change.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:52:17 +02:00
Lukasz Lenart 3432433e38 chore(agents): defines a new AGENTS.md focused on reporting vulnerabilities (#1680)
* chore(agents): defines a new AGENTS.md focused on reporting vulnerabilities

* chore(security): makes SECURITY.md the source of truth

* Fix typos in SECURITY.md and minor grammar correction

* chore(security): clarify public GitHub repo PoC counts as disclosure

Per @ppkarwasz review on #1680: expand the PoC bullet to make explicit
that pushing a PoC to a public GitHub repo, gist, fork, or branch is
public disclosure, and note that private repos require granting access
to each PMC member individually.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: René Gielen <rgielen@apache.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 13:27:53 +02:00
Lukasz Lenart 09d03286f8 WW-5626 per-property authorization for Jackson REST handlers (#1674)
* WW-5626 spike: validate Jackson per-property authorization mechanism

Validates that the Approach C design is feasible before committing to a detailed
implementation plan. Wraps each SettableBeanProperty via BeanDeserializerModifier;
intercepts deserializeAndSet to authorize against a path built from a ThreadLocal
Deque; uses skipChildren() to discard unauthorized values; uses [0] suffix for
collection/map/array elements to match ParametersInterceptor depth semantics.

Findings:
- Delegating base class via 'protected delegate' field is the right pattern
- addOrReplaceProperty(prop, true) is the correct builder API
- Reject-at-parent skips all nested deserialization (better security than two-phase
  copy: setter side effects on unauthorized properties never fire)
- JavaType#isCollectionLikeType/isMapLikeType/isArrayType detects the indexed-path case

Spike is kept under .../spike/ as a learning artifact; it will be replaced by
production code + tests in subsequent commits.

* WW-5626 add ParameterAuthorizationContext for deserializer-level authorization

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WW-5626 address review feedback on ParameterAuthorizationContext

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* WW-5626 add AuthorizationAwareContentTypeHandler marker interface

* WW-5626 add AuthorizingSettableBeanProperty for Jackson per-property authorization

* WW-5626 add ParameterAuthorizingModule installing the property wrapper on Jackson mappers

* WW-5626 register ParameterAuthorizingModule on default Jackson REST handlers

* WW-5626 use AuthorizationAwareContentTypeHandler path when handler supports it

* WW-5626 add integration tests proving the new Jackson authorization path is used

* WW-5626 deprecate XStreamHandler in favor of JacksonXmlHandler

* WW-5626 remove Jackson auth spike; replaced by production tests

* WW-5626 make JuneauXmlHandler authorization-aware via post-parse walk

Implements AuthorizationAwareContentTypeHandler. When ParameterAuthorizationContext
is active (set by ContentTypeInterceptor when requireAnnotations=true), the handler
walks the parsed result tree and copies only authorized properties to the target,
descending into nested beans/collections/maps/arrays with indexed-path semantics
([0] suffix) for parity with ParametersInterceptor.

Note: Juneau parses the entire result tree before our walk runs, so setter side
effects on transient nested objects can fire even for unauthorized properties —
those transient objects are then discarded. This is functionally equivalent to the
legacy two-phase copy in ContentTypeInterceptor; only the Jackson handlers achieve
the stronger guarantee where unauthorized subtrees are never instantiated at all
(they use Jackson's BeanDeserializerModifier + skipChildren).

When no context is bound (default config), behavior is unchanged: parser.parse +
BeanUtils.copyProperties.

* WW-5626 add JuneauXmlHandler integration tests for @StrutsParameter authorization

* WW-5626 test(rest): cover JuneauXmlHandler post-parse walk for collections, maps, arrays

Sonar reported 51 uncovered new lines in JuneauXmlHandler (48.8% coverage on the
post-parse authorization walk — the security-critical code path the branch exists
to introduce). Add integration coverage for the previously-uncovered branches:

- collection-of-scalars (List<String> tags)
- collection-of-beans (List<Address> addresses)
- map-of-scalars (Map<String,String> attributes)
- array-of-scalars (String[] aliases)
- empty collection
- malformed XML wrapped as IOException

Also drop two unnecessary casts (Sonar S1905) on lines 243/252 — the unchecked
conversion happens at the return statement, the explicit casts were redundant
under the existing @SuppressWarnings("unchecked").

Add @Override on the inline AnyConstraintMatcher.matches override (Sonar S1161).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5626 test(rest): cover AuthorizingSettableBeanProperty builder-path deserialization

Sonar reported 11 uncovered new lines on AuthorizingSettableBeanProperty (66.7%
coverage). All 11 are in deserializeSetAndReturn — the alternate Jackson entry
point used for builder-pattern deserialization, never triggered by setter-based
fixtures like Person.

Add an @JsonDeserialize(builder=...) fixture (ImmutablePerson) that forces
Jackson to use BuilderBasedDeserializer, which dispatches property writes
through deserializeSetAndReturn. Three new tests exercise the path:
inactive-context pass-through, top-level authorization, and full rejection.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* WW-5626 refactor(rest): extract helpers from ContentTypeInterceptor.intercept

Sonar S3776 flagged intercept() at cognitive complexity 16 (limit 15). Extract
the body-handling branches into named helpers:

- openBodyReader: encoding-aware reader from the request InputStream
- applyRequestBody: dispatcher between requireAnnotations on/off paths
- applyWithAuthorizationContext: bind + delegate + unbind for AuthorizationAware handlers
- applyTwoPhaseDeserialize: legacy fresh-instance + copyAuthorizedProperties path

intercept() drops to ~12 lines and reads as a flat sequence: resolve target,
delegate body application, invoke. Each helper carries the comment that
explains the security model for its branch.

Add @Override on the inline AnyConstraintMatcher.matches override (Sonar S1161).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 15:01:00 +02:00
dependabot[bot] a48f57d161 build(deps): bump slf4j.version from 2.0.17 to 2.0.18 (#1683)
Bumps `slf4j.version` from 2.0.17 to 2.0.18.

Updates `org.slf4j:slf4j-api` from 2.0.17 to 2.0.18

Updates `org.slf4j:slf4j-simple` from 2.0.17 to 2.0.18

---
updated-dependencies:
- dependency-name: org.slf4j:slf4j-api
  dependency-version: 2.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.slf4j:slf4j-simple
  dependency-version: 2.0.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-14 14:58:10 +02:00
dependabot[bot] 9c8d3de0e4 build(deps): bump github/codeql-action from 4.35.3 to 4.35.4 (#1682)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.3 to 4.35.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v4.35.3...v4.35.4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-14 14:57:50 +02:00
dependabot[bot] e5aa3e98a6 build(deps): bump com.github.ben-manes.caffeine:caffeine (#1679)
Bumps [com.github.ben-manes.caffeine:caffeine](https://github.com/ben-manes/caffeine) from 3.2.3 to 3.2.4.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.2.3...v3.2.4)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-version: 3.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-09 13:49:55 +02:00
dependabot[bot] 56b9b6807e build(deps): bump org.owasp:dependency-check-maven from 12.2.1 to 12.2.2 (#1677)
Bumps [org.owasp:dependency-check-maven](https://github.com/dependency-check/DependencyCheck) from 12.2.1 to 12.2.2.
- [Release notes](https://github.com/dependency-check/DependencyCheck/releases)
- [Changelog](https://github.com/dependency-check/DependencyCheck/blob/main/CHANGELOG.md)
- [Commits](https://github.com/dependency-check/DependencyCheck/compare/v12.2.1...v12.2.2)

---
updated-dependencies:
- dependency-name: org.owasp:dependency-check-maven
  dependency-version: 12.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-09 13:49:01 +02:00
dependabot[bot] fd05da73fa build(deps): bump org.glassfish.jaxb:jaxb-bom from 4.0.7 to 4.0.8 (#1676)
Bumps org.glassfish.jaxb:jaxb-bom from 4.0.7 to 4.0.8.

---
updated-dependencies:
- dependency-name: org.glassfish.jaxb:jaxb-bom
  dependency-version: 4.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-09 13:48:48 +02:00
dependabot[bot] c9cfa36cb2 build(deps): bump github/codeql-action from 4.35.2 to 4.35.3 (#1675)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.35.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v4.35.2...v4.35.3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-09 13:48:28 +02:00
Lukasz Lenart 690c4c2737 WW-5626 cleanup follow-ups for @StrutsParameter JSON/REST enforcement (#1673)
* WW-5626 add ParameterAuthorizer#resolveTarget for centralized ModelDriven resolution

Move the ValueStack peek logic that derives the target object from action+ModelDriven
state out of ParametersInterceptor and into ParameterAuthorizer. Callers that need
both authorization and the resolved target (for downstream OGNL allowlisting) can
now call resolveTarget once and reuse the result.

* WW-5626 delegate ModelDriven target resolution to ParameterAuthorizer

Replace the inline ValueStack peek in ParametersInterceptor#isParameterAnnotatedAndAllowlist
with a call to ParameterAuthorizer#resolveTarget. The ModelDriven import is no longer
needed in this class.

* WW-5626 defensively skip non-String JSON keys in authorization filter

The (String) cast in filterUnauthorizedKeysRecursive threw ClassCastException
for any custom JSONReader producing non-String keys. Replace with an instanceof
pattern that debug-logs and skips entries whose key cannot be converted to a
parameter path.

* WW-5626 add real JacksonJsonHandler integration tests for @StrutsParameter filtering

The existing ContentTypeInterceptorTest uses mock ContentTypeHandlers, so its
requireAnnotations=true tests verify only that intercept() returns SUCCESS — they
assert nothing about which properties were actually filtered. These integration
tests use a real JacksonJsonHandler + a real StrutsParameterAuthorizer to verify
end-to-end property-level filtering for top-level annotated/unannotated properties
and nested properties at varying authorized depths.

The SecureRestAction fixture documents a semantic divergence: REST's recursive
copy authorizes each path level independently, so depth-0 authorization on the
top-level property requires @StrutsParameter on the setter even when nested
field access is the actual goal. ParametersInterceptor only requires the getter
annotation. This divergence is tracked for the Approach C refactor.

* WW-5626 make ParameterAuthorizer#resolveTarget a default method to preserve SAM

Making resolveTarget abstract broke ParameterAuthorizer as a functional interface,
which the existing JSON and REST plugin tests rely on for lambda-based stubs:
  interceptor.setParameterAuthorizer((parameterName, target, action) -> true);

The default returns the action unchanged — adequate for lambda test stubs whose
authorization decisions don't depend on the resolved target. The production
implementation (StrutsParameterAuthorizer) overrides this with the proper
ModelDriven value-stack peek.
2026-05-09 12:09:03 +02:00
dependabot[bot] 7799c0fd2a build(deps): bump commons-io:commons-io from 2.21.0 to 2.22.0 (#1672)
Bumps commons-io:commons-io from 2.21.0 to 2.22.0.

---
updated-dependencies:
- dependency-name: commons-io:commons-io
  dependency-version: 2.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 16:00:19 +02:00
dependabot[bot] 11e815f26b build(deps): bump com.fasterxml.jackson:jackson-bom (#1669)
Bumps [com.fasterxml.jackson:jackson-bom](https://github.com/FasterXML/jackson-bom) from 2.21.2 to 2.21.3.
- [Commits](https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.21.2...jackson-bom-2.21.3)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson:jackson-bom
  dependency-version: 2.21.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 15:56:23 +02:00