Skip to content

WW-5618 feat(json): add configurable limits for DoS prevention#1626

Open
lukaszlenart wants to merge 1 commit intorelease/struts-6-8-xfrom
feat/WW-5618-json-configurable-limits-s6
Open

WW-5618 feat(json): add configurable limits for DoS prevention#1626
lukaszlenart wants to merge 1 commit intorelease/struts-6-8-xfrom
feat/WW-5618-json-configurable-limits-s6

Conversation

@lukaszlenart
Copy link
Member

@lukaszlenart lukaszlenart commented Mar 17, 2026

Summary

  • Adds configurable limits to the JSON plugin to prevent denial-of-service attacks via malicious JSON payloads (deeply nested, huge arrays, long strings)
  • Enforces limits directly in the existing JSONReader class — no interface extraction, no class renames, preserving full backward compatibility with Struts 6.x
  • Ports the security benefit of PR WW-5618 Add configurable limits to JSON plugin #1625 (Struts 7.x/main) to the 6.x release branch

New configurable constants (with defaults in struts-plugin.xml):

Constant Default Purpose
struts.json.maxElements 10,000 Max elements per object/array
struts.json.maxDepth 64 Max nesting depth
struts.json.maxLength 2,097,152 Max input length (chars)
struts.json.maxStringLength 262,144 Max string value length
struts.json.maxKeyLength 512 Max object key length

Files changed

File Change
JSONConstants.java 5 new constant definitions
JSONReader.java Limit fields, setters, enforcement in object()/array()/string()
JSONUtil.java New deserializeInput() instance method with length checking
JSONInterceptor.java Limit fields with @Inject setters, uses deserializeInput()
struts-plugin.xml Default constant values
JSONReaderLimitsTest.java New — 14 tests for limit enforcement
JSONUtilTest.java 4 new tests for deserializeInput() and maxLength

Test plan

  • ./mvnw -pl plugins/json clean test — all 125 tests pass (0 failures, 0 errors)
  • ./mvnw -pl plugins/json clean prepare-package -DskipTests — RAT license headers pass
  • No jakarta.servlet imports (verified javax.servlet namespace)
  • Uses com.opensymphony.xwork2.inject imports (not org.apache.struts2.inject)
  • Verify limits are effective with real-world payloads in showcase app

🤖 Generated with Claude Code

…evention

Add configurable limits to the JSON plugin to prevent denial-of-service
attacks via malicious JSON payloads. Limits are enforced directly in the
existing JSONReader class without breaking backward compatibility (no
interface extraction or class renames).

New configurable constants (struts-plugin.xml defaults):
- struts.json.maxElements (10000) - per-container element count
- struts.json.maxDepth (64) - maximum nesting depth
- struts.json.maxLength (2097152) - maximum input length in chars
- struts.json.maxStringLength (262144) - maximum string value length
- struts.json.maxKeyLength (512) - maximum object key length

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
25 Security Hotspots
42.6% Coverage on New Code (required ≥ 80%)
3.4% Duplication on New Code (required ≤ 3%)
E Security Rating on New Code (required ≥ A)
E Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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