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

rombert pushed a commit to branch issue/finalise-threat-model
in repository https://gitbox.apache.org/repos/asf/sling.git

commit d7a434f31f1344f8ecc6474080f3b1965c3ea1b2
Author: Robert Munteanu <[email protected]>
AuthorDate: Tue Jun 2 12:20:22 2026 +0200

    feat(threat-model): finalise model based on maintainer answers
---
 docs/threat-model.md | 235 +++++++++++++++++++++++++++++----------------------
 1 file changed, 136 insertions(+), 99 deletions(-)

diff --git a/docs/threat-model.md b/docs/threat-model.md
index 7cc6537..5008103 100644
--- a/docs/threat-model.md
+++ b/docs/threat-model.md
@@ -5,17 +5,18 @@
 - **Project**: Apache Sling — a set of Java OSGi bundles for building RESTful, 
content-driven web applications backed by a JCR repository. This model covers 
the engine, API bundles, scripting integrations, JCR integration, 
authentication handlers, content distribution, the OSGi installer / 
bundle-install path, the repoinit DSL, the XSS API, and the operator surfaces 
(Web Console, JMX, WebDAV/DavEx). Example assemblies (Sling Starter, Sling CMS) 
and build-time tooling are explicitly place [...]
 - **Version / commit**: Written against the Apache Sling source tree as of 
**2026-06-01** (315 `org-apache-sling-*` modules present).
 - **Author**: Sling PMC (draft, AI-assisted, derived outside-in from public 
artifacts).
-- **Status**: **Draft v1 — for Sling PMC review.** Derived from the published 
security policy, the project wiki, published CVE advisories, and source 
inspection. The model was additionally informed by the project's historical 
private security-list triage practice (no private discussion, reporter, or 
individual is reproduced here — only positions that are public policy or are 
visible in published CVE advisories). No question wave has yet been answered by 
the current PMC; every architectur [...]
-- **Version binding**: Single model, tracking **HEAD**. A report against a 
specific bundle version is triaged against the model as written here; when the 
model changes, the change is dated in this header and past triage decisions may 
be revisited. The unit of supported product is the **individual OSGi bundle**, 
not an assembly *(inferred — §14 W1Q1; strongly supported by the per-bundle 
release cadence and the security-policy dependency stance)*.
+- **Status**: **Draft v6 — all four question waves and all three 
meta-questions ratified by the maintainer on 2026-06-02.** Every body claim is 
`(documented)` or `(maintainer)`; **no `(inferred)` claims remain.** The model 
is complete at the claim level and ready for wider Sling PMC review; once 
accepted it is the canonical Sling threat model (§13 dispositions remain 
provisional per M1). Derived from the published security policy, the project 
wiki, published CVE advisories, and source in [...]
+- **Version binding**: Single model, tracking **HEAD**. A report against a 
specific bundle version is triaged against the model as written here; when the 
model changes, the change is dated in this header and past triage decisions may 
be revisited. The unit of supported product is the **individual OSGi bundle**, 
not an assembly *(maintainer, Wave 1 2026-06-02)*.
 - **Reporting cross-reference**: Findings that violate a §8 property of a 
specific bundle must be reported privately to **`[email protected]`** 
per the [Sling security 
policy](https://sling.apache.org/project-information/security.html) and the 
[ASF process](https://apache.org/security/committers.html). Findings that fall 
under §3 (out of scope) or §9 (disclaimed properties) will be acknowledged and 
typically closed with a pointer to this document.
-- **Relationship to existing security documents**:
-  - The [published security 
policy](https://sling.apache.org/project-information/security.html) 
(`security.html`) remains canonical for the **reporting process** and the two 
high-level non-findings it already states (vulnerable dependencies; generic 
DoS). This document is the detailed companion: scope, trust boundaries, 
claimed/disclaimed prope`r`ties, triage dispositions. It must remain a **strict 
superset** of `security.html` — nothing `security.html` asserts is weakened 
here (Appendix [...]
-  - The CWiki page [*Threat 
model*](https://cwiki.apache.org/confluence/display/SLING/Threat+model) (last 
modified 2023-06-26) is an **early stub**: it is marked DRAFT, references 
STRIDE/OWASP without applying them, and contains a single substantive paragraph 
(the Web Console must be restricted to fully-trusted operators). It is **not** 
an audit or risk register, so the "do not silently supersede a prior audit" 
rule does not bite — but the coexistence of two pages titled "Threat model" m 
[...]
+- **Location / canonical status** *(maintainer, 2026-06-02 — M2)*: this 
document is the **canonical Sling threat model**, kept as Markdown at 
**`aggregator/docs/threat-model.md`** in the `sling-aggregator` repo. It is 
deliberately **not** rendered as a `sling.apache.org` website page; the website 
security policy and the CWiki link *to* it. The **Sling Security Team owns 
drift detection** — before any release or edit that touches `security.html`, 
the CWiki page, or this document, the team [...]
+- **Relationship to existing security documents** *(maintainer, 2026-06-02 — 
M2)*:
+  - The [published security 
policy](https://sling.apache.org/project-information/security.html) 
(`security.html`) remains canonical for the **reporting process** and the two 
high-level non-findings it already states (vulnerable dependencies; generic 
DoS). It stays the reporting front door and links here. This document is the 
detailed companion: scope, trust boundaries, claimed/disclaimed properties, 
triage dispositions. It must remain a **strict superset** of `security.html` — 
nothing `s [...]
+  - The CWiki page [*Threat 
model*](https://cwiki.apache.org/confluence/display/SLING/Threat+model) (last 
modified 2023-06-26) is an **early stub** (marked DRAFT, references 
STRIDE/OWASP without applying them, one substantive paragraph: the Web Console 
must be restricted to fully-trusted operators). **This document supersedes 
it**; the stub is to be replaced by a link here. The stub's one substantive 
claim is preserved as a §8 property (operator surface, #15) and a §10 
responsibility.
 - **Provenance legend**:
   - *(documented)* — stated in `sling.apache.org`, the CWiki, a bundle 
README/Javadoc, or a published CVE advisory. Cited inline.
-  - *(maintainer)* — stated by a Sling PMC member in response to a §14 
question raised by *this* process. None yet — this is a first draft.
-  - *(inferred)* — reasoned from code structure, the pattern across published 
CVEs, or domain knowledge; not yet ratified for the current model. Every such 
tag has a matching §14 question.
-- **Draft confidence**: **~65 documented inline tags / 0 maintainer / ~62 
inferred tags.** The documented claims rest on `security.html`, the CWiki, 
bundle Javadoc/source inspection, the project's published CVE advisories (9 
issued Sling CVEs), and the project's documented security-team triage practice. 
The inferred tags concentrate in the architectural framing (§2 role 
decomposition, §4 boundaries, §5 environment, in/out rulings) — each routes to 
a §14 question. **No claim has been rati [...]
+  - *(maintainer)* — ratified by the maintainer in response to a §14 question 
raised by *this* process. Wave 1 was answered on 2026-06-02; those tags carry 
the date.
+  - *(inferred)* — reasoned from code structure, the pattern across published 
CVEs, or domain knowledge; not yet ratified. Every such tag would have a 
matching §14 question — **none remain in this draft** (all promoted to 
*(maintainer)* across Waves 1–4).
+- **Draft confidence**: **~64 documented / ~70 maintainer / 0 inferred** 
(inline tags). The documented claims rest on `security.html`, the CWiki, bundle 
Javadoc/source inspection, the project's published CVE advisories (9 issued 
Sling CVEs), and documented security-team triage practice. The maintainer tags 
are the Waves 1–4 ratifications (all 2026-06-02). **No `(inferred)` body claims 
remain** — the model is fully ratified at the claim level. The only open items 
are the three meta-questi [...]
 
 **One-paragraph description**. Apache Sling is a framework of Java OSGi 
bundles for building RESTful, content-driven web applications backed by a JCR 
repository (typically Apache Jackrabbit Oak). Its organising idea is *URL → JCR 
resource → script*: an incoming HTTP request path is resolved to a node in a 
content tree, the node's `sling:resourceType` selects a rendering script 
(HTL/Sightly, JSP, and optionally JavaScript/Groovy/FreeMarker/Thymeleaf), and 
the script renders the response.  [...]
 
@@ -25,15 +26,15 @@
 
 **Primary intended use** *(documented — sling.apache.org)*: a framework for 
RESTful, content-driven web applications backed by a JCR repository, "from 
simple websites to complex web applications". It is a **library/framework set 
deployed as a long-running network service**, not a CLI, not an embedded 
library used in isolation, and not a sandbox.
 
-**Unit of supported product** *(inferred — §14 W1Q1)*: **the individual OSGi 
bundle**. Each bundle is released and versioned on its own and carries its own 
§8 properties. Assemblies (Sling Starter, Sling CMS, downstream products) are 
compositions owned by the integrator. The model never treats "what the Starter 
does by default" as a Sling property — see §3.
+**Unit of supported product** *(maintainer, Wave 1 2026-06-02)*: **the 
individual OSGi bundle**. Each bundle is released and versioned on its own and 
carries its own §8 properties. Assemblies (Sling Starter, Sling CMS, downstream 
products) are compositions owned by the integrator. The model never treats 
"what the Starter does by default" as a Sling property — see §3.
 
 **Deployment contexts**:
 - **Custom assemblies** built via the Feature Model toolchain are the 
production norm. The integrator selects bundles, configures them, and owns the 
resulting composition.
-- **Sling Starter** is an *example* assembly used for integration testing and 
demonstration; its defaults are dev-convenience, not a hardened production 
posture *(inferred — §14 W1Q1)*.
+- **Sling Starter** is an *example* assembly used for integration testing and 
demonstration; its defaults are dev-convenience, not a hardened production 
posture *(maintainer, Wave 1 2026-06-02)*.
 - **Sling CMS** (`org-apache-sling-app-cms`) is another example/reference 
assembly maintained by the project. It has been the subject of its own CVE 
(CVE-2023-22849, stored/reflected XSS in CMS UI) *(documented — published CVE 
advisory)*.
 - **Library use** of individual API bundles (`api`, `models-api`, `commons-*`) 
embedded into other applications.
 
-**Caller / role decomposition** *(inferred — §14 W1Q8)*. Sling is a network 
service, so "the caller" splits into several actors with different trust levels:
+**Caller / role decomposition** *(maintainer, Wave 1 2026-06-02 — ratified as 
correct and complete)*. Sling is a network service, so "the caller" splits into 
several actors with different trust levels:
 
 | Role | Trust level | Typical channel |
 |---|---|---|
@@ -90,19 +91,19 @@
 
 ### Out-of-scope code shipped in the repository
 
-- **Samples & demo content** (`samples/`, `*-examples`, `starter-content`, 
`hapi-samplecontent`, `*-it-services`, `hc-samples`, `validation-examples`): 
illustrative, not for production. Reports against shipped scripts here → 
`OUT-OF-MODEL: unsupported-component` *(inferred — §14 W3Q1)*.
-- **Archetypes** (`*-archetype/`): Maven scaffolding; generated code is the 
integrator's *(inferred — §14 W3Q1)*.
-- **Committer / release tooling** (`tooling-github/jenkins/release/scm`, 
`committer-cli`, `slingpackager`, `ide-tooling`): out of layer *(inferred — §14 
W3Q1)*.
-- **Feature Model build-time tooling** (`slingfeature-maven-plugin`, 
`feature-launcher-maven-plugin`, `feature-cpconverter`, and Maven plugins 
generally): build-tool security is the integrator's CI concern. This is 
consistent with the established treatment of build/test-scope dependencies as 
out of scope *(inferred — §14 W2Q11; partially documented)*.
+- **Samples & demo content** (`samples/`, `*-examples`, `starter-content`, 
`hapi-samplecontent`, `*-it-services`, `hc-samples`, `validation-examples`): 
illustrative, not for production. Reports against shipped scripts here → 
`OUT-OF-MODEL: unsupported-component` *(maintainer, Wave 3 2026-06-02)*.
+- **Archetypes** (`*-archetype/`): Maven scaffolding; generated code is the 
integrator's *(maintainer, Wave 3 2026-06-02)*.
+- **Committer / release tooling** (`tooling-github/jenkins/release/scm`, 
`committer-cli`, `slingpackager`, `ide-tooling`): out of layer *(maintainer, 
Wave 3 2026-06-02)*.
+- **Feature Model build-time tooling** (`slingfeature-maven-plugin`, 
`feature-launcher-maven-plugin`, `feature-cpconverter`, and Maven plugins 
generally): build-tool security is the integrator's CI concern. 
(`feature-cpconverter` is build-time; the *runtime* package factories are in 
model — see §4 reachability and §8.) *(maintainer, Wave 2 2026-06-02)*
 - **Website & dist mirrors** (`site/`, `dist/`, `dist-dev/`): 
content-integrity is ASF infrastructure's concern. Precedent: a report of an 
exposed `/.git` directory on the project website was handled as a 
**website-infrastructure hygiene fix in the `sling-site` repo, not a product 
vulnerability** (the site source is already public on 
`github.com/apache/sling-site`) *(documented — Sling security-team practice)*.
 - **`private/`, `tmp/`**: not shipped components.
-- **Test-only bundles** (`*-it`, `testing-*`, `junit-*`, `paxexam-util`, 
`testing-clients`): must never be installed into a production runtime 
*(inferred — §14 W3Q1)*.
-- **Assembly-level defaults** (Starter ACLs, Starter bundle list, Felix Web 
Console default credentials, the example JCR `admin` password). Per-bundle 
defaults are in §5a; *assembly* defaults are the integrator's choice, not a 
Sling bundle property *(inferred — §14 W1Q1)*.
+- **Test-only bundles** (`*-it`, `testing-*`, `junit-*`, `paxexam-util`, 
`testing-clients`): must never be installed into a production runtime 
*(maintainer, Wave 3 2026-06-02)*.
+- **Assembly-level defaults** (Starter ACLs, Starter bundle list, Felix Web 
Console default credentials, the example JCR `admin` password). Per-bundle 
defaults are in §5a; *assembly* defaults are the integrator's choice, not a 
Sling bundle property *(maintainer, Wave 1 2026-06-02)*.
 
 ### Other out-of-scope threats
 
 - **Compromise of an authenticated administrator / a bundle with code-deploy 
rights.** This is the single most explicit boundary in established Sling 
security practice: the ability to deploy code into the OSGi container is 
treated as total compromise, so any "exploit" that first requires deploying a 
bundle or holding administrative privileges is out of scope. (An 
expression-language-injection report against `pipes` was rejected on exactly 
this basis — it required administrative privilege [...]
-- **Multi-tenant isolation within a single JVM.** Sling is single-tenant per 
JVM; OSGi visibility is the only inter-bundle isolation. Multi-tenancy requires 
separate JVMs *(inferred — §14 W1Q7)*.
+- **Multi-tenant isolation within a single JVM.** Sling is single-tenant per 
JVM; OSGi visibility is the only inter-bundle isolation. Multi-tenancy requires 
separate JVMs *(maintainer, Wave 1 2026-06-02)*.
 - **Side channels** (timing, cache, power) — see §9; the only place they could 
matter is `commons-crypto`, and even there constant-time is not claimed by 
default.
 - **Networking below TLS** (BGP, DNS, ARP), **local privilege escalation on 
the host**, and **the build/release pipeline** (TB5) — all out of layer / 
ASF-level.
 
@@ -154,32 +155,32 @@ For each family, the condition a finding must meet to be 
in-model:
 - **`engine`, `auth-*`, `servlets-{get,post,resolver}`, `resourceresolver`, 
`xss`, `rewriter`, `resourcemerger`**: in-model iff reachable from a TB1 HTTP 
request at the relevant §2 role.
 - **`servlets-resolver` / `ResourceUtil.normalize`**: in-model iff a crafted 
URL can cause a script to be resolved/executed **outside the configured search 
paths** — this is exactly the CVE-2024-23673 class (a `normalize` flaw that 
left `/../` in the path and bypassed `isPathAllowed()`) *(documented — 
CVE-2024-23673 advisory)*.
 - **`scripting-*`**: in-model iff invoked while resolving a script for an 
attacker-influenceable resource path. A bug only reachable via a script the 
attacker did not place (a sample/demo component never deployed) is 
`OUT-OF-MODEL: unsupported-component`.
-- **`installer-provider-jcr` / `-file`**: in-model iff a **low-privilege** 
principal can cause a bundle install via a configured watch path. "An 
admin/operator installed a malicious bundle" is by design (TB4 trusted) 
*(inferred — §14 W2Q8; supported by established Sling security-team practice on 
code-deploy scope)*.
+- **`installer-provider-jcr` / `-file`**: in-model iff a **low-privilege** 
principal can cause a bundle install via a configured watch path. "An 
admin/operator installed a malicious bundle" is by design (TB4 trusted) 
*(maintainer, Wave 2 2026-06-02)*.
 - **`servlets-post`**: in-model iff a low-privilege HTTP role can reach a 
write the model claims is gated by the requesting principal's JCR session.
-- **`distribution-*`**: distribution authenticates the *peer* (HTTP Basic, 
OAuth, mTLS, or Kafka SASL/ACL) but **does not authenticate payloads**. 
In-model iff either (a) an unauthenticated party bypasses peer-authentication 
and writes to the receiver, or (b) an authenticated peer violates a property 
*other than* payload integrity (crash, super-linear consumption, JCR-session 
escape). A *legitimate* peer sending a malicious payload is `BY-DESIGN: 
property-disclaimed` *(inferred — §14 W2Q9)*.
-- **`installer-factory-packages`, `jcr-contentloader`, 
`feature-extension-content`**: live runtime; packages are trusted input 
(operator-supplied) with no built-in authorship verification. In-model iff a 
low-priv principal can supply a package to one of these factories via a 
reachable path *(inferred — §14 W2Q11)*.
-- **`repoinit-parser`, `jcr-repoinit`**: parsed input is operator-controlled. 
A finding against the parser itself on adversarial input is `OUT-OF-MODEL: 
trusted-input`; a bundle that fed *untrusted* content to the parser is the bug 
*(inferred — §14 W2Q10)*.
+- **`distribution-*`**: distribution authenticates the *peer* (HTTP Basic, 
OAuth, mTLS, or Kafka SASL/ACL) but **does not authenticate payloads**. 
In-model iff either (a) an unauthenticated party bypasses peer-authentication 
and writes to the receiver, or (b) an authenticated peer violates a property 
*other than* payload integrity (crash, super-linear consumption, JCR-session 
escape). A *legitimate* peer sending a malicious payload is `BY-DESIGN: 
property-disclaimed` *(maintainer, Wave 2 [...]
+- **`installer-factory-packages`, `jcr-contentloader`, 
`feature-extension-content`**: live runtime; packages are trusted *for 
authorship* (operator-supplied; no cryptographic authorship verification — §9), 
but package **processing** is expected to be defensive: it should not amplify a 
decompression bomb, burn super-linear CPU, or let extraction escape the 
package's declared target paths. In-model iff a low-priv principal can supply a 
package to one of these factories via a reachable path [...]
+- **`repoinit-parser`, `jcr-repoinit`**: parsed input is operator-controlled. 
A finding against the parser itself on adversarial input is `OUT-OF-MODEL: 
trusted-input`; a bundle that fed *untrusted* content to the parser is the bug 
*(maintainer, Wave 2 2026-06-02)*.
 - **Web Console, JMX, DavEx, WebDAV, `mcp-server`**: in-model iff reachable 
from TB1 (i.e., these surfaces were left exposed to unauthenticated traffic by 
an assembly's mounts/ACLs). Operator deliberately exposing them is 
`OUT-OF-MODEL: trusted-input`.
 
 ---
 
 ## §5 Assumptions about the environment
 
-*(All entries inferred unless tagged; §14 W2 carries the questions. The 
negative-claims inventory was spot-checked against core-bundle source on 
2026-06-01.)*
+*(Environment assumptions and the negative-claims inventory were ratified in 
Wave 2 (2026-06-02); the inventory was spot-checked against core-bundle source 
on 2026-06-01.)*
 
-- **Runtime**: Java 8 minimum, Java 11 the primary LTS baseline *(documented — 
[Java version support 
wiki](https://cwiki.apache.org/confluence/display/SLING/Java+version+support); 
2019, may be stale — §14 W2Q13a)*; recent bundles raise this (e.g., 
`commons-log` 5.5.0 requires Java 11 per the CVE-2023-6378 advisory). OSGi R7+ 
on Apache Felix.
+- **Runtime**: **There is no single supported JVM version for "Sling".** 
Consistent with the per-bundle unit of supported product (§2), each OSGi bundle 
or tooling project chooses the Java version it runs on; across current bundles 
this spans **Java 8 to 21**, set by each bundle's inherited Sling parent-pom 
configuration (the parent pom is the source of truth, not the stale 2019 "Java 
version support" wiki page). A single minimum-Java figure is a property of a 
*distribution* (e.g., the S [...]
 - **Repository**: Apache Jackrabbit Oak. **Oak ACLs/permissions are 
authoritative for content access; Sling does not re-implement or override 
repository authorization** (§8 property 2, §9 disclaimer on Oak semantics).
 - **Concurrency**: Sling services are expected to be thread-safe. Scripts and 
Sling Models run on the request thread; thread-safety of *developer-introduced* 
mutable state is the developer's responsibility — see the Sling Models 
session-leak rejection in §11 *(documented — Sling security-team practice)*.
 - **Time**: system clock used for session expiry, distribution timestamps, 
scheduler firing.
 - **Filesystem**: `installer-provider-file` watches configured directories; 
write access there equals OSGi bundle-install rights (TB4).
 - **Network**: TLS termination is the deployer's responsibility (reverse proxy 
/ Dispatcher). Sling does not assume the wire is encrypted.
 
-**Negative claims — what Sling does *not* do to its host** *(inferred — §14 
W2Q13; core bundles spot-checked 2026-06-01)*:
+**Negative claims — what Sling does *not* do to its host** *(maintainer, Wave 
2 2026-06-02; core bundles spot-checked 2026-06-01)*:
 
 - **Child processes**: no `Runtime.exec` / `ProcessBuilder` in core (`engine`, 
`servlets-post`, `servlets-resolver`, `auth-core` confirmed clean). *Outside* 
core, `commons-messaging-mail`, `clam`, and the JSP/Groovy/JS scripting engines 
can spawn by design.
 - **Environment variables**: one opt-in exception — `resourceresolver`'s 
`StringInterpolationProviderImpl` calls `System.getenv` for OSGi-configured 
placeholder substitution in resolver mappings (confirmed present 2026-06-01). 
Operator-driven, not load-time.
-- **Global JVM state**: scoped exceptions only — `jaxp-configurator` 
deliberately sets JVM-wide JAXP factory defaults (the documented XXE 
mitigation, §10); `commons-scheduler` sets 
`org.terracotta.quartz.skipUpdateCheck=true` at activation; `commons-log` 
transiently sets `java.util.logging.config.class` in a try/finally; 
`feature-launcher` sets slf4j system properties at launch (launcher only). 
*(inferred — §14 W2Q13)*
-- **Signal handlers / shutdown hooks**: none in core runtime bundles; 
`feature-launcher` registers a shutdown hook to stop the framework cleanly 
(launcher only). *(inferred — §14 W2Q13)*
+- **Global JVM state**: scoped exceptions only — `jaxp-configurator` 
deliberately sets JVM-wide JAXP factory defaults (the documented XXE 
mitigation, §10); `commons-scheduler` sets 
`org.terracotta.quartz.skipUpdateCheck=true` at activation; `commons-log` 
transiently sets `java.util.logging.config.class` in a try/finally; 
`feature-launcher` sets slf4j system properties at launch (launcher only). 
*(maintainer, Wave 2 2026-06-02)*
+- **Signal handlers / shutdown hooks**: none in core runtime bundles; 
`feature-launcher` registers a shutdown hook to stop the framework cleanly 
(launcher only). *(maintainer, Wave 2 2026-06-02)*
 
 ---
 
@@ -189,18 +190,18 @@ For each family, the condition a finding must meet to be 
in-model:
 
 | Bundle / knob | Bundle default | Effect | Stance |
 |---|---|---|---|
-| `jcr-base` `LoginAdminWhitelist` | Empty (deny) | Which bundles may call 
`loginAdministrative` | Safe default; assembler adds entries explicitly 
*(inferred — §14 W2)* |
+| `jcr-base` `LoginAdminWhitelist` | Empty (deny) | Which bundles may call 
`loginAdministrative` | Safe default; assembler adds entries explicitly 
*(maintainer, Wave 4 2026-06-02)* |
 | `serviceusermapper.amended` | None | Maps OSGi bundle → JCR principal | Each 
bundle needing a service user declares its mapping; otherwise privileged login 
denied |
 | `installer-provider-jcr` watch paths | None | JCR paths bundles install from 
| In-model only if a low-priv principal can write to a configured path (§4) |
-| `security` `ReferrerFilter` | Active when installed; conservative allow-list 
| Anti-CSRF for state-changing requests | Per-bundle property §8 #12 *(inferred 
— §14 W3)* |
+| `security` `ReferrerFilter` | Active when installed; conservative allow-list 
| Anti-CSRF for state-changing requests | Per-bundle property §8 #12 
*(maintainer, Wave 4 2026-06-02)* |
 | `security` `ContentDispositionFilter` | Disabled until configured with paths 
| Forces `Content-Disposition: attachment` for binary downloads | Property §8 
#13 holds when enabled+configured |
 | `jaxp-configurator` | When installed and started **first**, sets JVM-global 
JAXP factories to safe (XXE-off) defaults | Disables XXE in JAXP | Required 
mitigation for assemblies parsing user XML/PDF/Office *(documented — 
CVE-2025-66516 advisory)* |
-| `auth-core` `sling.auth.requirements` | No path authenticated until 
configured | Which paths require auth | Per-assembly config *(inferred — §14 
W2)* |
+| `auth-core` `sling.auth.requirements` | No path authenticated until 
configured | Which paths require auth | Per-assembly config *(maintainer, Wave 
4 2026-06-02)* |
 | `jcr-resourcesecurity` | `ResourceAccessGate` for JCR; per-config | 
Provider-context access gating | *(documented — resource-access-security)* |
 | `extensions-webconsolesecurityprovider` | Replaces Felix default Web Console 
auth with JCR-backed auth when installed | Web Console hardening building block 
| Opt-in |
 | `distribution-*` receive endpoint | Disabled until configured with peer 
identity | Accepts content from peers | Per-assembly config |
 | `engine` include content-type-conflict check | **Off by default** (opt-in) | 
Throws when an included servlet sets a conflicting content-type — the 
CVE-2022-45064 hardening | Kept off-by-default for backward compatibility; may 
flip after "a sufficient period" *(documented — CVE-2022-45064 advisory)* |
-| `mcp-server` | Opt-in; not in Starter | Exposes a Model Context Protocol 
surface | Operator-only surface *(inferred — §14 W1Q4)* |
+| `mcp-server` | Opt-in; not in Starter | Exposes a Model Context Protocol 
surface | Operator-only surface, same posture as the Web Console *(maintainer, 
Wave 1 2026-06-02)* |
 
 ### Scripting-engine bundle install (TB4 expansion)
 
@@ -208,13 +209,13 @@ Installing a scripting bundle adds an engine that 
executes scripts resolved from
 
 | Bundle | §8 contextual-escape contract? | Status |
 |---|---|---|
-| `scripting-sightly-*` (HTL) | **Yes** — contextual auto-escape (§8 #4) | 
First-class, canonical *(inferred — §14 W1Q5; well-documented in HTL spec)* |
-| `scripting-jsp*` | **No** — authors must encode via `xss` `XSSAPI` | In 
scope; primary alongside HTL *(inferred — §14 W1Q5a)* |
-| `scripting-javascript` (Rhino), `-groovy`, `-freemarker`, `-thymeleaf`, 
`-esx` | **No** | In scope as bundles (memory/correctness still apply) but **no 
encoding/sandboxing claim**; JSP/Groovy/JS reach full Java *(inferred — §14 
W1Q5b)* |
+| `scripting-sightly-*` (HTL) | **Yes** — contextual auto-escape (§8 #4) | 
First-class, canonical *(maintainer, Wave 1 2026-06-02; well-documented in HTL 
spec)* |
+| `scripting-jsp*` | **No** — authors must encode via `xss` `XSSAPI` | In 
scope; primary alongside HTL *(maintainer, Wave 1 2026-06-02)* |
+| `scripting-javascript` (Rhino), `-groovy`, `-freemarker`, `-thymeleaf`, 
`-esx` | **No** | In scope as bundles (memory/correctness still apply) but **no 
encoding/sandboxing claim**; JSP/Groovy/JS reach full Java *(maintainer, Wave 1 
2026-06-02)* |
 
 ### Insecure-default rulings (proposed — §14 W1)
 
-- **Felix Web Console default credentials**, **example JCR `admin` password**: 
any "default `admin`/`admin` in production" report → `OUT-OF-MODEL: 
non-default-build`. The wiki threat-model stub already states operators must 
restrict the console *(documented — CWiki Threat model; §14 W1Q2/Q3 to ratify 
the disposition)*.
+- **Felix Web Console default credentials**, **example JCR `admin` password**: 
any "default `admin`/`admin` in production" report → `OUT-OF-MODEL: 
non-default-build`. The wiki threat-model stub already states operators must 
restrict the console *(documented — CWiki Threat model; disposition ratified 
maintainer, Wave 1 2026-06-02)*.
 - **Distribution receive endpoint** left open: a finding is `VALID` only if 
peer-authentication can be *bypassed*; an operator who configured no peer 
identity and exposed it is `OUT-OF-MODEL: trusted-input`.
 
 ---
@@ -245,8 +246,8 @@ Sling is a network service; the first column is the 
route/protocol message, not
 
 ### Size / shape / rate assumptions
 
-- **Per-request body size**: bounded by the servlet container; Sling imposes 
no global cap *(inferred)*.
-- **Per-node property size / tree depth**: bounded by Oak; Sling does not 
validate further *(inferred)*.
+- **Per-request body size**: bounded by the servlet container; Sling imposes 
no global cap *(maintainer, Wave 4 2026-06-02)*.
+- **Per-node property size / tree depth**: bounded by Oak; Sling does not 
validate further *(maintainer, Wave 4 2026-06-02)*.
 - **Parser nesting depth**: the canonical Sling JSON/template parsers must not 
recurse unbounded on attacker-controlled nesting (CVE-2022-47937 lesson); the 
*retired* `commons-json` does, which is why migration — not a depth limit — is 
the stated remedy.
 - **Rate**: no Sling-layer rate limiting — generic DoS is the deployer's 
problem *(documented)*.
 
@@ -258,7 +259,7 @@ Sling is a network service; the first column is the 
route/protocol message, not
 
 - **Anonymous TB1 attacker** — arbitrary HTTP, including malformed framing. 
Goals: RCE (script execution via resolution bypass or write-then-render), auth 
bypass, content tampering, disclosure of non-public content.
 - **Low-privilege authenticated user** — holds a legitimate JCR principal with 
limited ACLs. Goals: privilege escalation across ACL boundaries; reaching a 
privileged `sling:resourceType`/script; the author→admin escalation realised by 
CVE-2024-23673.
-- **Authenticated-but-Byzantine distribution peer (TB2)** — holds a legitimate 
peer identity, can produce any payload. Goals: corrupting replicated content; 
crashing the receiver with malformed packages. Honest-fraction threshold is 
**not formalised**; typical deployment is one author → N publish receivers, and 
an attacker controlling the author has fully compromised the system *(inferred 
— §14 W2Q9)*.
+- **Authenticated-but-Byzantine distribution peer (TB2)** — holds a legitimate 
peer identity, can produce any payload. Goals: corrupting replicated content; 
crashing the receiver with malformed packages. Honest-fraction threshold is 
**not formalised**; typical deployment is one author → N publish receivers, and 
an attacker controlling the author has fully compromised the system 
*(maintainer, Wave 2 2026-06-02)*.
 - **Crafted-input attacker** — supplies PDF/Office/XML for Tika parsing; 
supplies deeply-nested JSON/XML to a parser; supplies adversarial 
selectors/paths; supplies CRLF in URLs (log-injection, CVE-2022-32549).
 
 ### Capabilities / limits
@@ -288,17 +289,17 @@ Each property: statement + conditions; violation symptom; 
severity tier; provena
 
 2. **JCR (Oak) ACLs are authoritative for content access; Sling does not 
bypass them.** A principal without `jcr:read` cannot read a node via 
`ResourceResolver`; a principal without write rights cannot modify it via 
`SlingPostServlet`. (Sling's commitment is *non-bypass*; the *semantics* of 
Oak's evaluation belong to Jackrabbit — §9.)
    - Violation symptom: read/write succeeds for a principal Oak's ACL denies, 
due to Sling using a more-privileged session or skipping the session.
-   - Severity: **CVE-class**. *(inferred — §14 W3Q14)*
+   - Severity: **CVE-class**. *(maintainer, Wave 3 2026-06-02)*
 
 3. **Bundle install requires write access to a configured install path.** Only 
a principal with write rights on `/apps/*/install` (or another configured path) 
can cause `installer-provider-jcr`/`-file` to install a bundle.
    - Violation symptom: a bundle installs from an unauthorised path or by a 
principal lacking that write right.
-   - Severity: **CVE-class** (full RCE). *(inferred — §14 W2Q8)*
+   - Severity: **CVE-class** (full RCE). *(maintainer, Wave 2 2026-06-02)*
 
 ### Scripting / output encoding
 
 4. **HTL / Sightly is a contextual auto-escaping template language.** A 
`${expression}` emits content escaped for the surrounding 
HTML/attribute/JS/URI/CSS context; the compiler infers context and applies the 
matching filter. **This applies only to HTL** — not JSP, not any other engine.
    - Violation symptom: a value emitted via standard HTL syntax appears 
unescaped for its context (explicit `@context='unsafe'` is a documented escape 
— §9).
-   - Severity: **CVE-class** for the HTL bundles. *(inferred — §14 W1Q5; 
well-documented in HTL spec)*
+   - Severity: **CVE-class** for the HTL bundles. *(maintainer, Wave 1 
2026-06-02; well-documented in HTL spec)*
 
 5. **`org.apache.sling.xss.XSSAPI` / `XSSFilter` produce output safe for the 
*requested* context.** The right `encodeForX` call yields output safe to emit 
in context X (HTML body, attribute, JS, URI, CSS). JSP and non-HTL templates 
are expected to call into this bundle.
    - Violation symptom: input survives the *correct* `encodeForX` for its 
context and still executes there.
@@ -312,17 +313,17 @@ Each property: statement + conditions; violation symptom; 
severity tier; provena
    - Bundle: `servlets-post`.
    - Violation symptom: SlingPostServlet performs a write via an elevated 
session for a non-elevated request, or bypasses the session entirely.
    - **Out of property:** "Oak allowed X it shouldn't have" → routes to 
Jackrabbit (§9).
-   - Severity: **CVE-class**. *(inferred — §14 W3Q14)*
+   - Severity: **CVE-class**. *(maintainer, Wave 3 2026-06-02)*
 
 ### Authentication
 
 7. **Authentication handlers either authenticate or pass through; they never 
silently elevate.** A handler that fails to authenticate leaves the request 
anonymous; it does not yield a session for another principal.
    - Violation symptom: a request becomes authenticated as principal P without 
valid credentials for P.
-   - Severity: **CVE-class**. *(inferred — §14 W2)*
+   - Severity: **CVE-class**. *(maintainer, Wave 4 2026-06-02)*
 
 8. **OAuth/OIDC and SAML2 handlers verify the cryptographic envelope** 
(`auth-oauth-client`, `auth-saml2`): state/nonce, audience, issuer, signature, 
expiry.
    - Violation symptom: an unsigned, expired, replayed, or wrong-audience 
assertion produces a session.
-   - Severity: **CVE-class**. *(inferred — §14 W2)*
+   - Severity: **CVE-class**. *(maintainer, Wave 4 2026-06-02)*
 
 ### Resource consumption
 
@@ -332,12 +333,12 @@ Each property: statement + conditions; violation symptom; 
severity tier; provena
    - Severity:
      - **CVE-class** when the blowup is easily reachable by a *single, small, 
attacker-controlled* input via TB1. **Realised cases:** CVE-2023-26513 
(repeated merge-root segments in a `resourcemerger` path spike CPU) and 
CVE-2022-47937 (unbounded recursion on nesting depth in the retired 
`commons-json` parser → StackOverflow/OOM) *(documented — CVE-2023-26513 and 
CVE-2022-47937 advisories)*.
      - **VALID-HARDENING** when the blowup needs careful crafting, large 
multi-step inputs, or rare runtime conditions.
-   - *(documented threshold; severity calibration inferred — §14 W3Q17)*
+   - *(documented threshold; severity calibration maintainer, Wave 3 
2026-06-02)*
 
 ### Output integrity
 
 10. **`rewriter` does not itself introduce XSS;** transformations emitting 
attacker-controlled content do so through the configured escaping policy.
-    - Severity: **CVE-class** for the bundle. *(inferred — §14 W3)*
+    - Severity: **CVE-class** for the bundle. *(maintainer, Wave 4 2026-06-02)*
 
 11. **Logging does not allow log forging via request data.** Values derived 
from a request (URL, headers) that reach the log are neutralised against 
CRLF/control-character injection.
     - Violation symptom: a request containing `%0A%0D…` forges fake log lines 
(log injection / log forging).
@@ -349,49 +350,55 @@ Each property: statement + conditions; violation symptom; 
severity tier; provena
     - Bundles: `distribution-{api,core,journal,journal-kafka}`.
     - Violation symptom: a request without/with-forged peer credentials 
mutates the receiver; or the digest check fails to reject a corrupted payload.
     - Severity: **CVE-class** for peer-auth bypass / digest-check bypass.
-    - **Explicitly disclaimed:** payload integrity between authenticated peers 
(§9). *(inferred — §14 W2Q9)*
+    - **Explicitly disclaimed:** payload integrity between authenticated peers 
(§9). *(maintainer, Wave 2 2026-06-02)*
 
 ### Configuration / CSRF
 
 13. **`ReferrerFilter` rejects state-changing requests whose Referer/Origin is 
not allow-listed** (default-deny for cross-origin POST/PUT/DELETE). This CSRF 
protection is treated as load-bearing — it was the basis for declining a 
POST-only XSS report on the grounds that the cross-origin write could not be 
triggered (the CVE-2019-0198 withdrawal; see §11a) *(documented — CVE-2019-0198 
reservation/withdrawal)*.
     - Violation symptom: a cross-origin write succeeds despite a 
non-whitelisted Referer.
-    - Severity: **CVE-class** for the bundle. *(inferred — §14 W3)*
+    - Severity: **CVE-class** for the bundle. *(maintainer, Wave 4 2026-06-02)*
 
 14. **`ContentDispositionFilter` forces `Content-Disposition: attachment` for 
binary downloads under configured paths**, mitigating XSS via uploaded SVG/HTML.
     - Violation symptom: a binary from a configured path is served without the 
header.
-    - Severity: **CVE-class** for the bundle. *(inferred — §14 W3)*
+    - Severity: **CVE-class** for the bundle. *(maintainer, Wave 4 2026-06-02)*
 
 15. **The OSGi Web Console is a fully-privileged operator surface that must be 
access-restricted.** *"Access to the Web Console must be restricted and only 
permitted to users trusted with total control over the deployment"* 
*(documented — CWiki Threat model)*. Sling provides 
`extensions-webconsolesecurityprovider` as a hardening building block; the 
network/credential restriction itself is the operator's (§10).
     - Severity: **CVE-class** if a Sling bundle weakens an operator's 
configured restriction; the *absence* of a restriction in an example assembly 
is `OUT-OF-MODEL: non-default-build`.
 
+### Content-package processing
+
+15a. **Runtime content-package processing is expected to be resource-bounded 
and to confine extraction to declared paths.** Although a package's 
*authorship* is trusted (§9), the factories that unpack FileVault packages at 
runtime (`installer-factory-packages`, `jcr-contentloader`, 
`feature-extension-content`) should not be defeated by a *malformed* package: 
no decompression-bomb amplification, no super-linear CPU on a small package, 
and no extraction writing outside the package's declar [...]
+    - Violation symptom: a small crafted package exhausts memory/CPU on 
unpack, or an entry escapes the target subtree and writes to an unintended 
repository/filesystem path.
+    - Severity: **`VALID-HARDENING`** — the project elects to harden these, 
fixed at maintainer discretion; not held to the CVE-class bar that §8 #1–#3 
carry. *(maintainer, Wave 2 2026-06-02)*
+
 ---
 
 ## §9 Security properties Sling does *not* provide
 
 - **No defense against generic DoS** *(documented)*: streaming-bomb uploads, 
request floods, repeated identical requests, slowloris — deployer rate-limits 
at the edge.
-- **No transport security (TLS)** — deployer terminates upstream *(inferred — 
§14 W2)*.
-- **No rate limiting / brute-force protection** on login endpoints *(inferred 
— §14 W2)*.
-- **No multi-tenant isolation within a single JVM** *(inferred — §14 W1Q7)*.
+- **No transport security (TLS)** — deployer terminates upstream *(maintainer, 
Wave 4 2026-06-02)*.
+- **No rate limiting / brute-force protection** on login endpoints 
*(maintainer, Wave 4 2026-06-02)*.
+- **No multi-tenant isolation within a single JVM** *(maintainer, Wave 1 
2026-06-02)*.
 - **No sandbox for bundle code, or for non-HTL script engines.** A bundle, or 
a JSP/Groovy/JS script, runs as full Java; the ability to deploy code is 
treated as total compromise (§3, §7) *(documented — Sling security-team 
practice)*.
 - **No CSRF protection if `ReferrerFilter` is disabled/misconfigured** by the 
operator.
-- **No constant-time comparison guarantees anywhere** unless a specific 
bundle's docs explicitly claim it (none do by default). Treat any equality 
check on a secret as non-constant-time *(inferred — §14 W3Q16)*.
-- **No auto-escaping in JSP or in 
JavaScript/Groovy/FreeMarker/Thymeleaf/ESX.** Only HTL escapes for you; for 
everything else the author must call `XSSAPI`. JSTL `<c:out>` is a language 
convention, not a Sling property *(inferred — §14 W1Q5a/Q5b)*.
+- **No constant-time comparison guarantees anywhere** unless a specific 
bundle's docs explicitly claim it (none do by default). Treat any equality 
check on a secret as non-constant-time *(maintainer, Wave 3 2026-06-02)*.
+- **No auto-escaping in JSP or in 
JavaScript/Groovy/FreeMarker/Thymeleaf/ESX.** Only HTL escapes for you; for 
everything else the author must call `XSSAPI`. JSTL `<c:out>` is a language 
convention, not a Sling property *(maintainer, Wave 1 2026-06-02)*.
 - **`XSSAPI.getValidHref` does not enforce a safe URL scheme** — see §8 #5. 
Syntactic validity ≠ semantic safety *(documented — `xss` Javadoc + source 
inspection)*.
-- **No payload integrity/authenticity in distribution between authenticated 
peers.** A peer with a legitimate identity can ship arbitrary content; Sling 
does not sign/MAC payloads *(inferred — §14 W2Q9)*.
-- **No content-package signature verification.** `installer-factory-packages`, 
`feature-extension-content`, `jcr-contentloader` accept FileVault packages 
without authorship verification *(inferred — §14 W2Q11)*.
-- **No defensive parsing of `repoinit` input** — the parser assumes 
operator-controlled input *(inferred — §14 W2Q10)*.
-- **No claim on Oak's ACL evaluation semantics** — reports of the shape "Oak 
permitted X" route to Jackrabbit, not Sling *(inferred — §14 W3Q14)*.
-- **No script-source confidentiality.** Scripts under `/apps`/`/libs` are 
*content*; their readability is whatever the assembly's JCR ACLs allow. Secrets 
in script source is a §11 misuse, not a Sling failure *(inferred — §14 W3Q18)*.
-- **No assembly-level guarantee.** Properties attach to bundles, not to the 
Starter/Sling CMS as a whole *(inferred — §14 W1Q1)*.
+- **No payload integrity/authenticity in distribution between authenticated 
peers.** A peer with a legitimate identity can ship arbitrary content; Sling 
does not sign/MAC payloads *(maintainer, Wave 2 2026-06-02)*.
+- **No content-package *authorship* verification.** 
`installer-factory-packages`, `feature-extension-content`, `jcr-contentloader` 
accept FileVault packages without any cryptographic check of who authored them 
— package signing, if required, is an operator/CI concern. (This is distinct 
from package *processing* safety, which §8 #15a does expect — 
bombs/CPU/extraction-traversal.) *(maintainer, Wave 2 2026-06-02)*
+- **No defensive parsing of `repoinit` input** — the parser assumes 
operator-controlled input *(maintainer, Wave 2 2026-06-02)*.
+- **No claim on Oak's ACL evaluation semantics** — reports of the shape "Oak 
permitted X" route to Jackrabbit, not Sling *(maintainer, Wave 3 2026-06-02)*.
+- **No script-source confidentiality.** Scripts under `/apps`/`/libs` are 
*content*; their readability is whatever the assembly's JCR ACLs allow. Secrets 
in script source is a §11 misuse, not a Sling failure *(maintainer, Wave 3 
2026-06-02)*.
+- **No assembly-level guarantee.** Properties attach to bundles, not to the 
Starter/Sling CMS as a whole *(maintainer, Wave 1 2026-06-02)*.
 - **`getValidHref`, MIME detection, and the distribution `Digest` header are 
not the security primitives they resemble** — see false friends below.
 
 ### False friends (look like a security primitive; are not)
 
 - **`XSSAPI.getValidHref` is not a safe-URL gate** — it validates href 
*syntax*, not scheme; `data:` and others pass *(documented — `xss` Javadoc + 
source inspection)*.
-- **`commons-mime` content-type detection is advisory, not a security gate.** 
Treating detected MIME as proof of file shape is unsafe — Sling and downstream 
parsers (e.g., Tika) may disagree *(inferred — §14 W3Q15)*.
-- **The distribution HTTP `Digest` header is a corruption checksum, not a 
MAC** *(inferred — §14 W2Q9)*.
-- **`commons-crypto` is a convenience layer**; it accepts algorithms (short 
MACs, deprecated ciphers) that look usable but are inappropriate for new 
designs, and makes no constant-time guarantee *(inferred — §14 W3Q15)*.
-- **A JCR session is an authorization context, not a MAC of its contents** 
*(inferred — §14 W3Q15)*.
+- **`commons-mime` content-type detection is advisory, not a security gate.** 
Treating detected MIME as proof of file shape is unsafe — Sling and downstream 
parsers (e.g., Tika) may disagree *(maintainer, Wave 3 2026-06-02)*.
+- **The distribution HTTP `Digest` header is a corruption checksum, not a 
MAC** *(maintainer, Wave 2 2026-06-02)*.
+- **`commons-crypto` is a convenience layer**; it accepts algorithms (short 
MACs, deprecated ciphers) that look usable but are inappropriate for new 
designs, and makes no constant-time guarantee *(maintainer, Wave 3 2026-06-02)*.
+- **A JCR session is an authorization context, not a MAC of its contents** 
*(maintainer, Wave 3 2026-06-02)*.
 
 ### Well-known attack classes left to the caller
 
@@ -410,7 +417,7 @@ Each property: statement + conditions; violation symptom; 
severity tier; provena
 The deployer / assembler must:
 
 1. **Build a non-vulnerable assembly** — Sling depends on the lowest 
compatible versions; you pick the resolution *(documented)*.
-2. **Treat the Starter as a starting point, not a production runtime** — 
harden every default *(inferred — §14 W1Q1)*.
+2. **Treat the Starter as a starting point, not a production runtime** — 
harden every default *(maintainer, Wave 1 2026-06-02)*.
 3. **Include and start `jaxp-configurator` first** in any assembly parsing 
user XML/PDF/Office *(documented — CVE-2025-66516)*.
 4. **Lock down the Web Console** — remove from production, restrict by 
network, or replace its auth with `extensions-webconsolesecurityprovider`; 
**change default credentials** *(documented — CWiki Threat model)*.
 5. **Change all default credentials**, including the JCR `admin` password, 
before any non-dev exposure.
@@ -453,8 +460,8 @@ The deployer / assembler must:
 *(Grounded in published CVE advisories and established Sling security-team 
triage practice.)*
 
 - **"Dependency X has CVE Z."** Not a Sling bug unless X is embedded, shipped 
directly in a Sling assembly, a Maven plugin, or Node.js (Dependabot policy). 
Verify *actual usage*, not just presence. `DEPENDENCY-NON-FINDING` *(documented 
— Dependabot wiki + Sling security-team practice)*.
-- **"Default `admin`/`admin` Web Console / JCR password in production."** 
`OUT-OF-MODEL: non-default-build` *(documented — CWiki stub; §14 W1Q2/Q3)*.
-- **"Sling Starter ships weak ACLs / anonymous can read `/content/*.json`."** 
Starter is an example assembly; production ACLs are the operator's. 
`OUT-OF-MODEL: non-default-build` *(inferred — §14 W1Q1)*.
+- **"Default `admin`/`admin` Web Console / JCR password in production."** 
`OUT-OF-MODEL: non-default-build` *(documented — CWiki stub; maintainer, Wave 1 
2026-06-02)*.
+- **"Sling Starter ships weak ACLs / anonymous can read `/content/*.json`."** 
Starter is an example assembly; production ACLs are the operator's. 
`OUT-OF-MODEL: non-default-build` *(maintainer, Wave 1 2026-06-02)*.
 - **"`/system/console/configMgr` exposes secrets."** Must not be on a public 
listener. `OUT-OF-MODEL: trusted-input`.
 - **"Crafted file download via the JSON renderer (e.g., suffix `.exe`)."** 
Treated as not exploitable — the response body is always valid JSON regardless 
of the suffix, so nothing executable is produced; a quality issue, not a 
vulnerability. `BY-DESIGN: property-disclaimed` *(documented — Sling 
security-team practice)*.
 - **"XSS in `HtmlResponse`/`location` via a POST parameter."** The reserved 
CVE-2019-0198 was **withdrawn** — judged not exploitable because the vector is 
a POST request and cross-origin writes are blocked by CSRF protection (§8 #13); 
fixed as defense-in-depth without a live CVE. `KNOWN-NON-FINDING` *(documented 
— CVE-2019-0198 reservation/withdrawal)*.
@@ -467,11 +474,12 @@ The deployer / assembler must:
 - **"Streaming X GB to a POST exhausts memory."** Generic DoS. `BY-DESIGN: 
property-disclaimed` *(documented)*.
 - **"`commons-json` OOM/StackOverflow on nested input."** Accepted as 
CVE-2022-47937 with **no code fix** — the module is retired; remedy is 
migration to Johnzon. A report on the retired module → point to the advisory 
and Johnzon; not a fixable Sling bug *(documented — CVE-2022-47937 advisory)*.
 - **"Tika XXE/SSRF via attacker PDF."** If the assembly included and started 
`jaxp-configurator`, a mitigation failure is `VALID` against that bundle; if it 
didn't, the assembly choice is `OUT-OF-MODEL: trusted-input` against Sling. The 
Tika exposure itself is punted upstream to Jackrabbit Oak / Tika *(documented — 
CVE-2025-66516 advisory)*.
+- **"`installer-factory-packages` accepts an unsigned / unauthenticated 
content package."** By design — there is no cryptographic authorship 
verification; the operator owns the package supply chain. `BY-DESIGN: 
property-disclaimed` (§9). **But** a *malformed* package that bombs memory/CPU 
on unpack or escapes its declared paths on extraction is a different report — 
that is `VALID-HARDENING` per §8 #15a, not by-design. *(maintainer, Wave 2 
2026-06-02)*
 - **"`/.git` exposed on sling.apache.org."** Website-infrastructure hygiene, 
fixed in `sling-site`; the site source is already public, so it discloses 
nothing new. `OUT-OF-MODEL: unsupported-component` (site/infra) *(documented — 
Sling security-team practice)*.
-- **"`commons-scheduler` sets `org.terracotta.quartz.skipUpdateCheck`; 
`commons-log` sets `java.util.logging.config.class`; `feature-launcher` 
registers a shutdown hook."** All scoped/by-design (§5). `KNOWN-NON-FINDING` 
*(inferred — §14 W2Q13)*.
-- **"`resourceresolver` reads environment variables."** 
`StringInterpolationProviderImpl` reads `System.getenv` for operator-configured 
placeholders — opt-in, operator-controlled. `OUT-OF-MODEL: trusted-input` 
*(inferred — §14 W2Q13)*.
-- **"Oak permitted access I didn't expect."** Routes to Jackrabbit/Oak — Sling 
claims non-bypass, not Oak's evaluation semantics. *(inferred — §14 W3Q14)*
-- **"Non-constant-time equality in an auth bundle."** Generically disclaimed 
(§9). `BY-DESIGN: property-disclaimed` unless that bundle's docs claimed 
constant-time *(inferred — §14 W3Q16)*.
+- **"`commons-scheduler` sets `org.terracotta.quartz.skipUpdateCheck`; 
`commons-log` sets `java.util.logging.config.class`; `feature-launcher` 
registers a shutdown hook."** All scoped/by-design (§5). `KNOWN-NON-FINDING` 
*(maintainer, Wave 2 2026-06-02)*.
+- **"`resourceresolver` reads environment variables."** 
`StringInterpolationProviderImpl` reads `System.getenv` for operator-configured 
placeholders — opt-in, operator-controlled. `OUT-OF-MODEL: trusted-input` 
*(maintainer, Wave 2 2026-06-02)*.
+- **"Oak permitted access I didn't expect."** Routes to Jackrabbit/Oak — Sling 
claims non-bypass, not Oak's evaluation semantics. *(maintainer, Wave 3 
2026-06-02)*
+- **"Non-constant-time equality in an auth bundle."** Generically disclaimed 
(§9). `BY-DESIGN: property-disclaimed` unless that bundle's docs claimed 
constant-time *(maintainer, Wave 3 2026-06-02)*.
 
 ---
 
@@ -486,13 +494,13 @@ Per the HEAD-tracking binding (§1), the model is revised 
in place. Triggers:
 - A default change to any §5a per-bundle knob that flips a security-relevant 
value (e.g., the engine include content-type check flipping on by default).
 - Distribution adds a transport or gains a payload-authenticity mechanism (§8 
#12 changes).
 - Adoption of mandatory bundle/package signing.
-- A change in the minimum Java version, OSGi framework, or Oak version.
+- A change in the OSGi framework or Jackrabbit Oak baseline. (Per-bundle Java 
baselines moving within the 8–21 range do **not** trigger a revision — there is 
no single Sling Java version per §5; a *distribution's* minimum is an assembly 
concern.)
 - **A vulnerability report that cannot be cleanly routed to a §13 
disposition** — the correct response is to revise the model (add the property 
to §8/§9), not to make an ad-hoc call.
-- **Drift between this document, `security.html`, and the CWiki Threat model 
page** — resolving the three-way coexistence (§14 M2) and keeping them 
consistent thereafter.
+- **Drift between this document, `security.html`, and the CWiki Threat model 
page** — the Sling Security Team checks the three for consistency before any 
release or edit touching them (§1, M2).
 
 ## §13 Triage dispositions
 
-> **Status: tentative** — the label set is proposed by this draft; the Sling 
PMC has not ratified it or aligned it with existing security-team practice 
(which historically operated without an explicit label vocabulary). Labels may 
be renamed/merged; the *closed-set* property and the section citations must be 
preserved (§14 M1).
+> **Status: provisional (maintainer, 2026-06-02 — M1).** The maintainer has 
**adopted** this closed label set, but explicitly marks it provisional and 
non-binding until the security team has applied it to real reports for a 
period, then revisits. Labels may be renamed or merged in that review; the 
*closed-set* property and the per-row section citations must be preserved 
through any change. The security team historically triaged without an explicit 
label vocabulary, so this set is new wor [...]
 
 | Disposition | Meaning | Licensed by |
 |---|---|---|
@@ -513,38 +521,67 @@ Per the HEAD-tracking binding (§1), the model is revised 
in place. Triggers:
 
 ## §14 Open questions for the maintainers
 
-Grouped in waves (skill §3.2). Each carries a **proposed answer** for the PMC 
to confirm, correct, or strike. Every *(inferred)* tag in the body routes to a 
question here; meta-questions (M1–M3) have no body claim behind them.
+Grouped in waves (skill §3.2). Each carried a **proposed answer** for the 
maintainer to confirm, correct, or strike. **All four waves and all three 
meta-questions are answered** (2026-06-02) and the corresponding body tags 
promoted to *(maintainer)*; the tables below are retained as a ratification 
record. No open questions remain.
+
+### Wave 1 — Scope and deployment shape ✅ ANSWERED (2026-06-02)
+
+All six question-clusters were ratified as proposed by the maintainer. 
Outcomes folded into §1, §2, §3, §5a, §8, §9, §10, §11a; the corresponding 
*(inferred)* tags were promoted to *(maintainer, Wave 1 2026-06-02)*.
+
+| Q | Answer | Folded into |
+|---|---|---|
+| W1Q1 — Unit of supported product | **Individual OSGi bundle.** Sling Starter 
/ Sling CMS are example assemblies; their defaults are dev-convenience, not 
Sling properties. Assembly-level reports are `OUT-OF-MODEL: assembly-level`. | 
§1, §2, §3, §5a, §9, §13 |
+| W1Q2 / Q3 — Default Web Console / JCR `admin` credentials | **`OUT-OF-MODEL: 
non-default-build`.** Operators must change credentials and network-restrict 
the console before non-dev exposure. | §5a, §10, §11a |
+| W1Q4 — `mcp-server` posture | **Operator-only, same posture as the Web 
Console.** Opt-in, not in Starter; reachable-from-untrusted is an assembly 
misconfiguration, not a bundle bug. | §5a, §10, §11a |
+| W1Q5 / Q5a / Q5b — Scripting escape contracts | **Only HTL/Sightly** carries 
a §8 contextual-auto-escape contract. JSP and 
JavaScript/Groovy/FreeMarker/Thymeleaf/ESX have no Sling-claimed escape 
contract; authors must call `XSSAPI`. | §5a, §8 #4/#5, §9 |
+| W1Q7 — Multi-tenant isolation | **Out of scope** — single-tenant per JVM; 
OSGi visibility is the only inter-bundle isolation. | §3, §9 |
+| W1Q8 — Role decomposition | **Correct and complete** as the eight-role §2 
table stands. | §2, §7 |
+
+### Wave 2 — Trust boundaries, reachability, environment ✅ ANSWERED 
(2026-06-02)
 
-### Wave 1 — Scope and deployment shape *(highest priority — reshapes 
§2/§3/§5a/§8/§9)*
+Ratified by the maintainer, with two refinements (W2Q11 and W2Q13). Outcomes 
folded into §4, §5, §6, §7, §8 (#3, #12, new #15a), §9, §10, §11a; tags 
promoted to *(maintainer, Wave 2 2026-06-02)*.
 
-- **W1Q1 — Unit of supported product.** *Proposed:* the individual OSGi 
bundle; Starter/Sling CMS are example assemblies and their defaults are 
dev-convenience, not Sling properties. → §1, §2, §3, §5a, §9, §13.
-- **W1Q2 / Q3 — Default Web Console / JCR `admin` credentials.** *Proposed:* 
`OUT-OF-MODEL: non-default-build`. → §5a, §10, §11a.
-- **W1Q4 — `mcp-server` posture.** *Proposed:* opt-in, not in Starter, same 
posture as Web Console. → §5a, §10.
-- **W1Q5 / Q5a / Q5b — Scripting escape contracts.** *Proposed:* only HTL has 
a §8 auto-escape contract; JSP and the others require explicit `XSSAPI`. → §5a, 
§8 #4/#5, §9.
-- **W1Q7 — Multi-tenant isolation.** *Proposed:* out of scope; single-tenant 
per JVM. → §3, §9.
-- **W1Q8 — Role decomposition.** *Proposed:* the §2 role table is correct and 
complete. → §2, §7.
+| Q | Answer | Folded into |
+|---|---|---|
+| W2Q8 — Installer reachability | **Low-priv principal only.** "An 
admin/operator installed a malicious bundle" is by design (code deploy = total 
compromise). | §4, §8 #3 |
+| W2Q9 — Distribution payload integrity | **Peer-authenticated only** — no 
payload signature/MAC/replay-nonce; the HTTP `Digest` header is a corruption 
checksum, not a MAC. Per-payload authenticity is signed externally by the 
operator. | §4, §7, §8 #12, §9, §10 |
+| W2Q10 — repoinit trusted input | **Operator-controlled (trusted).** A 
crash/hang/super-linear cost when parsing adversarial input is `OUT-OF-MODEL: 
trusted-input`; a bundle that feeds untrusted content to the parser is the bug. 
| §4, §6, §9 |
+| W2Q11 — Content-package / cpconverter trust | **`feature-cpconverter` is 
build-time (§3).** Runtime factories accept packages **without authorship 
verification** (unsigned-package report → `BY-DESIGN`). **Refinement:** package 
*processing* must still be defensive against malformed packages — decompression 
bombs, CPU exhaustion, and extraction path-traversal — modeled as a 
**`VALID-HARDENING`** expectation (new §8 #15a), *not* CVE-class. | §4, §8 
#15a, §9, §11a |
+| W2Q13 / Q13a — Negative env claims & Java baseline | **Env inventory 
confirmed** (no process-spawn/signal-handlers in core; one env-var read; four 
scoped global-state writes; one launcher shutdown hook). **Refinement:** there 
is **no single supported JVM version** — each bundle/tooling project chooses 
its own (range **8–21**, per the parent pom); a single minimum-Java is a 
*distribution* property, not a Sling property. The 2019 wiki figure (8 min / 11 
LTS) is superseded by this per-bun [...]
+
+### Wave 3 — Properties (§8/§9) ratification ✅ ANSWERED (2026-06-02)
 
-### Wave 2 — Trust boundaries, reachability, environment
+All five clusters (plus a scope-confirmation that fixed a dangling §3 tag) 
were ratified as proposed. Tags promoted to *(maintainer, Wave 3 2026-06-02)*.
 
-- **W2Q8 — Installer reachability.** *Proposed:* in-model only for a low-priv 
principal; "admin installed a bad bundle" is by design. → §4, §8 #3.
-- **W2Q9 — Distribution payload integrity.** *Proposed:* peer-authenticated 
only; no payload signature/MAC/replay nonce; `Digest` is a checksum. → §4, §7, 
§8 #12, §9, §10.
-- **W2Q10 — repoinit trusted input.** *Proposed:* parser input is 
operator-controlled; adversarial-input crashes are not Sling bugs. → §4, §6, §9.
-- **W2Q11 — Content-package / cpconverter trust.** *Proposed:* 
`feature-cpconverter` build-time (§3); runtime package factories accept 
packages without authorship verification. → §4, §9, §10.
-- **W2Q13 / Q13a — Negative environment claims & Java baseline.** *Proposed:* 
core does not spawn processes / install signal handlers; the env-var read and 
four global-state writes in §5 are the only exceptions; current Java baseline 
is 8 min / 11 LTS (confirm whether the 2019 wiki figure is still accurate). → 
§5, §11a.
+| Q | Answer | Folded into |
+|---|---|---|
+| W3Q14 — PostServlet/Oak split | **Session use only.** SlingPostServlet 
guarantees writes go through the requesting principal's JCR session; it makes 
**no** claim about Oak's ACL-evaluation semantics. "Oak permitted X" routes to 
Jackrabbit. | §8 #6, §9, §11a |
+| W3Q15 — False-friends list | **Correct and complete** — adopt the five 
entries as-is (getValidHref scheme, MIME advisory, Digest checksum, 
commons-crypto convenience, JCR session ≠ MAC). | §9 |
+| W3Q16 — Constant-time policy | **Generically disclaimed everywhere.** Assume 
any equality on a secret is non-constant-time unless a bundle's own docs claim 
otherwise; not enumerated per call site. | §9, §11a |
+| W3Q17 — Super-linear severity | **CVE-class only when small + 
easily-reachable + single-shot via TB1**; bugs needing crafting / large or 
multi-step inputs / rare conditions are `VALID-HARDENING`. | §8 #9, §11a |
+| W3Q18 — Script-source confidentiality | **Not confidential — scripts are 
content.** Readability is governed by the assembly's JCR ACLs; 
secrets-in-script-source is a §11 misuse, not a Sling failure. | §9, §11a |
+| (scope) Out-of-scope code | **Confirmed** — samples/demo content, 
archetypes, committer/release tooling, and test-only bundles are all 
`OUT-OF-MODEL: unsupported-component`. | §3 |
 
-### Wave 3 — Properties (§8/§9) ratification
+### Wave 4 — Residual property ratifications ✅ ANSWERED (2026-06-02)
 
-- **W3Q14 — PostServlet/Oak split.** *Proposed:* SlingPostServlet claims 
*correct session use*, not Oak's ACL semantics; "Oak permitted X" routes to 
Jackrabbit. → §8 #6, §9, §11a.
-- **W3Q15 — False-friends list.** *Proposed:* adopt the §9 list (getValidHref, 
MIME, Digest, commons-crypto, JCR session). → §9.
-- **W3Q16 — Constant-time policy.** *Proposed:* keep generic — assume 
non-constant-time everywhere unless a bundle's docs say otherwise. → §9, §11a.
-- **W3Q17 — Super-linear severity threshold.** *Proposed:* CVE-class only for 
small, easily-reachable, single-shot TB1 inputs; otherwise `VALID-HARDENING`. → 
§8 #9, §11a.
-- **W3Q18 — Script-source confidentiality.** *Proposed:* scripts are content; 
readability is per assembly ACLs; secrets-in-scripts is misuse. → §9, §11a.
+All five clusters ratified as proposed. Tags promoted to *(maintainer, Wave 4 
2026-06-02)*. With this wave, **every body claim is now `(documented)` or 
`(maintainer)`** — no `(inferred)` tags remain. Only the meta-questions (M1–M3) 
are open.
 
-### Open meta-questions for the PMC
+| Q | Answer | Folded into |
+|---|---|---|
+| W4Q1 — Auth-handler properties | **Confirmed** — handlers never silently 
elevate; OAuth/OIDC + SAML2 verify 
state/nonce/audience/issuer/signature/expiry. Both CVE-class §8 properties. | 
§8 #7, #8 |
+| W4Q2 — Filter / rewriter properties | **Confirmed** — `rewriter` does not 
itself introduce XSS; `ReferrerFilter` default-deny when active; 
`ContentDispositionFilter` forces attachment for configured paths. | §8 #10, 
#13, #14 |
+| W4Q3 — TLS and rate-limiting | **Confirmed deliberate §9 disclaimers** — 
neither transport security nor login throttling is provided; both are the 
deployer's edge responsibility. | §9, §10 |
+| W4Q4 — §5a knob defaults | **Confirmed accurate** — `LoginAdminWhitelist` 
empty/deny, `ReferrerFilter` active+conservative, `sling.auth.requirements` 
no-path-authenticated-until-configured. | §5a |
+| W4Q5 — Input size/shape limits | **Confirmed** — no Sling-layer request-body 
cap (servlet container bounds it); no per-node size/depth validation beyond 
Oak's own limits. | §6 |
+
+### Meta-questions ✅ ANSWERED (2026-06-02)
+
+| Q | Answer | Folded into |
+|---|---|---|
+| M1 — §13 label set | **Adopted, but marked provisional.** The closed label 
set stands as working terminology; §13 is flagged non-binding until the 
security team has applied it to real reports for a period, then revisits. The 
closed-set property and per-row §-citations are preserved through any later 
rename. | §13 status note |
+| M2 — Venue & coexistence | **This document is canonical, kept as 
`aggregator/docs/threat-model.md`** (not rendered as a website page). 
`security.html` stays the reporting front door and links here; the CWiki stub 
is superseded and replaced by a link. **The Sling Security Team owns drift 
detection** across the three artifacts. | §1 (location/relationship), §12 |
+| M3 — Practice-based tags | **Acceptable as stated.** The *(documented — 
Sling security-team practice)* positions reflect current policy and may be 
stated publicly as written; no private discussion is reproduced, so the tags 
stay as-is. | throughout (tags unchanged) |
 
-- **M1 — §13 label ratification.** Adopt the proposed closed set, or align to 
existing practice? In practice the team applies *de facto* categories 
(dependency-non-finding, code-deploy/admin-scope, app-vs-framework, 
opt-in-not-default hardening, unsupported-when-assigned for retired modules) 
but has no written label vocabulary. *Proposed:* adopt as drafted; rename if a 
house style emerges. → §13.
-- **M2 — Three-way coexistence and publication venue.** There are now three 
artifacts: `security.html` (process + 2 non-findings), the CWiki **Threat 
model** stub (one Web Console paragraph), and this document. *Proposed:* this 
document becomes canonical; the CWiki stub is replaced by a link to it; 
`security.html` stays as the reporting-process front door and links here. 
Publish at `site/.../project-information/threat-model.md`. Who owns drift 
detection going forward? → §1, §12.
-- **M3 — Security-team-practice `(documented)` tags.** Several claims are 
tagged *(documented — Sling security-team practice)* on the strength of how 
past security reports were triaged, summarised here as policy without 
reproducing any private discussion. *Proposed:* the PMC confirms these 
positions still reflect current policy and are acceptable to state in a public 
document. → throughout.
+*All four question waves and all three meta-questions are now resolved. 
Remaining `(inferred)` claims: none. This draft is ready for wider PMC review 
and, once accepted, becomes the canonical model per M2.*
 
 ---
 
@@ -585,4 +622,4 @@ Per the skill, a CVE list is not the threat model, but a 
*pattern across CVEs* i
 
 ---
 
-*This is a draft (v1). No claim is authoritative for triage until the PMC has 
answered the §14 waves and the inferred tags are promoted to (maintainer). 
Until then, use it as input to a conversation, not as triage policy. Claims 
attributed to "Sling security-team practice" reflect the project's historical 
triage of security reports; the PMC should confirm they remain current policy 
(§14 M3).*
+*Draft v6 (2026-06-02). All §14 question waves and meta-questions have been 
ratified by the maintainer; no `(inferred)` claims remain and the model is 
complete at the claim level, pending wider Sling PMC review before it is 
declared canonical (per M2). The §13 disposition labels are adopted 
**provisionally** (M1) and may be revised after use on real reports. Claims 
attributed to "Sling security-team practice" reflect the project's historical 
triage of security reports and have been confi [...]

Reply via email to