This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts.git


The following commit(s) were added to refs/heads/main by this push:
     new 74af1ef20 docs: tie the control test to the THREAT_MODEL §8 properties
74af1ef20 is described below

commit 74af1ef2091a1a0d7161fd6d8c0b44580fe13b23
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Oct 31 14:07:13 2026 +0100

    docs: tie the control test to the THREAT_MODEL §8 properties
    
    SECURITY.md said both that an unbounded read of request-derived input is in
    scope even when linear, and that a bound the framework never promised is
    hardening. For a read with no documented limit the two passages gave
    different answers, while S2-073 and S2-077 had already been handled as
    vulnerabilities.
    
    State what reconciles them: THREAT_MODEL §8.7 promises bounded consumption,
    and a §8 property is a claimed control for the purposes of the control test.
    Date the WW-5618 example accordingly (no bound promised, §8.7 not yet
    written), replace the container body-size example that contradicted §8.7,
    and write down the WW-5642 precedent for a control that is still being
    extended across input channels.
    
    Co-Authored-By: Claude Mythos 5.1 <[email protected]>
---
 SECURITY.md | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/SECURITY.md b/SECURITY.md
index 08d0c53d2..5d8d5b5aa 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -49,27 +49,37 @@ to consume resources in a non-linear relationship to the 
size of inputs.
 To be clear about the linear cases: that philosophy describes what we design 
against, not a threshold a
 report has to clear before we will accept it. Framework code that reads or 
retains request-derived input
 **without any bound** is in scope even where the growth is merely linear, and 
we have assigned CVEs for
-exactly that. What stays out of scope is the generic case above — where the 
cost to the server is
-proportionate, no framework limit is missing or ineffective, and the defence 
belongs to your servlet
-container, reverse proxy, or network.
+exactly that. The reason is the control test below: 
[`THREAT_MODEL.md`](THREAT_MODEL.md) §8.7 promises that
+framework code reads and retains request-derived input under a limit, and that 
promise is a claimed control.
+What stays out of scope is the generic case above — where the cost to the 
server is proportionate, no
+framework limit is missing or ineffective, and the defence belongs to your 
servlet container, reverse proxy,
+or network.
 
 ### Hardening or vulnerability: the control test
 
 The question we ask is not "can this input hurt a server" but "does the 
framework claim a control
-here, and does that control do what it says".
+here, and does that control do what it says". A control is claimed wherever 
the framework documents it: a
+setting, a limit, a filter, or one of the security properties in 
[`THREAT_MODEL.md`](THREAT_MODEL.md) §8.
 
 - **No control claimed.** Where the framework has never promised a bound or a 
check and the defence is
-  documented as the operator's or the application's (request-body size at the 
container, authentication,
-  CSRF tokens), a report that the framework does not supply it is handled as 
public hardening — a Jira
-  ticket, no bulletin, no CVE. The reporter is credited on the ticket.
+  documented as the operator's or the application's (authentication, CSRF 
tokens, connection and rate
+  limits at the container), a report that the framework does not supply it is 
handled as public hardening —
+  a Jira ticket, no bulletin, no CVE. The reporter is credited on the ticket.
 - **Control claimed but not enforced.** Where the framework documents a limit, 
a filter, or a policy and it
   does not hold for the inputs it targets, that is a vulnerability regardless 
of how the operator has
   configured anything else, and it is handled privately per this policy.
+- **Control still being extended.** A control the framework is rolling out 
across its input channels is
+  not broken on a channel it has not reached yet. A report that it does not 
cover such a channel is handled
+  as public hardening, and the fix must not regress a channel the control 
already covers. Extending the
+  `@StrutsParameter` control, new to the REST body path in 7.2.0, to the body 
properties it did not yet
+  reach ([WW-5642](https://issues.apache.org/jira/browse/WW-5642)) is the 
precedent. Where the control is
+  applied to a channel and does not hold there, the previous bullet applies.
 
 A consequence worth stating: **adding a control moves the line.** The same 
request that was a hardening
 report before a limit existed becomes a vulnerability report if the limit, 
once added, can be bypassed.
 The JSON plugin's input limits were added as hardening in
-[WW-5618](https://issues.apache.org/jira/browse/WW-5618) (6.9.0 / 7.2.1); the 
later finding that the
+[WW-5618](https://issues.apache.org/jira/browse/WW-5618) (6.9.0 / 7.2.1) — at 
that point the plugin
+promised no bound and §8.7 had not yet been written, so no control was 
claimed; the later finding that the
 length limit could be bypassed was CVE-2026-73633
 ([S2-072](https://cwiki.apache.org/confluence/display/WW/S2-072)). Those are 
two findings, not one, and
 they were credited separately.

Reply via email to