Copilot commented on code in PR #496:
URL: https://github.com/apache/jspwiki/pull/496#discussion_r3327735543


##########
draft-THREAT-MODEL.md:
##########
@@ -0,0 +1,1243 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# Apache JSPWiki Security Threat Model (draft)
+
+## §1 Header
+
+- **Project**: Apache JSPWiki — a Java/JSP wiki engine packaged as a servlet
+  webapp (WAR), deployed inside an operator-supplied servlet container
+  (Apache Tomcat 10.1+ recommended) on JDK 17+ *(documented: `README.md`)*.
+- **Repository scope**: `apache/jspwiki` only. `jspwiki-site` and
+  `jspwiki-asf-docs` are dormant and **out of scope** (confirmed by PMC chair
+  Juan Pablo Santos, 2026-05-30).
+- **Version / commit**: drafted against the default branch (`master`),
+  HEAD `be4ed49` ("use full artifact for javadocs doclet", 2026-05-28),
+  corresponding to development series `3.0.0-git-23`. A report against
+  released JSPWiki version *N* should be triaged against the model as it
+  stood at *N*, not at HEAD.
+- **Date**: 2026-05-30.
+- **Authors**: ASF Security team draft, awaiting JSPWiki PMC review.
+- **Status**: draft — under maintainer review.
+- **Reporting**: vulnerabilities that fall under §8 (claimed properties)
+  should be reported per the Apache Security Team disclosure channel
+  (<[email protected]>); reports that fall under §3 (out of
+  scope), §9 (properties not provided), or §11a (known non-findings)

Review Comment:
   The document names `<[email protected]>` as the Apache Security 
Team reporting channel, but later in the appendix it references 
`[email protected]`. This inconsistency is likely to misroute vulnerability 
reports. Please reconcile to the correct disclosure address(es) and, if both 
are valid (project alias + central ASF Security), state the preferred route and 
when to use each.



##########
draft-THREAT-MODEL.md:
##########
@@ -0,0 +1,1243 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# Apache JSPWiki Security Threat Model (draft)
+
+## §1 Header
+
+- **Project**: Apache JSPWiki — a Java/JSP wiki engine packaged as a servlet
+  webapp (WAR), deployed inside an operator-supplied servlet container
+  (Apache Tomcat 10.1+ recommended) on JDK 17+ *(documented: `README.md`)*.
+- **Repository scope**: `apache/jspwiki` only. `jspwiki-site` and
+  `jspwiki-asf-docs` are dormant and **out of scope** (confirmed by PMC chair
+  Juan Pablo Santos, 2026-05-30).
+- **Version / commit**: drafted against the default branch (`master`),
+  HEAD `be4ed49` ("use full artifact for javadocs doclet", 2026-05-28),
+  corresponding to development series `3.0.0-git-23`. A report against
+  released JSPWiki version *N* should be triaged against the model as it
+  stood at *N*, not at HEAD.
+- **Date**: 2026-05-30.
+- **Authors**: ASF Security team draft, awaiting JSPWiki PMC review.
+- **Status**: draft — under maintainer review.
+- **Reporting**: vulnerabilities that fall under §8 (claimed properties)
+  should be reported per the Apache Security Team disclosure channel
+  (<[email protected]>); reports that fall under §3 (out of
+  scope), §9 (properties not provided), or §11a (known non-findings)
+  will be closed by JSPWiki triagers citing this document. JSPWiki
+  additionally maintains a public CVE log at
+  `https://jspwiki-wiki.apache.org/Wiki.jsp?page=CVE` *(maintainer-published
+  artefact — not mined into this draft, see §14 Q1)*.
+- **Provenance legend** —
+  *(documented)* = drawn from in-repo docs, code, or website docs, with
+  citation;
+  *(maintainer)* = stated by a JSPWiki maintainer in response to this draft;
+  *(inferred)* = synthesized by the producer from code structure or domain
+  knowledge, awaiting PMC ratification (every *(inferred)* tag has a matching
+  §14 question).
+- **Draft confidence**: 38 documented / 1 maintainer / 27 inferred.
+
+JSPWiki is a long-lived wiki engine (origins in 2001) whose core abstractions
+are: a **WikiSession** (a long-running per-HTTP-session principal/Subject
+construct, see `org.apache.wiki.api.core.Session`); a **Engine** (process-
+global, holds page/attachment providers, plugin manager, authn/authz
+managers); a **markup parser** that translates JSPWiki syntax (or, optionally,
+Markdown) into XHTML; a **plugin/page-filter** subsystem that runs Java code
+inline as wiki pages are rendered or saved; and a JAAS-based AAA stack
+layered on top of either the servlet container's authentication or JSPWiki's
+own UserDatabase. Authorization is expressed as **Java 2-style permissions**
+(`PagePermission`, `WikiPermission`, `GroupPermission`, `AllPermission`)
+matched against a `WEB-INF/jspwiki.policy` security-policy file *and*, on a
+per-page basis, an inline **ACL** embedded in the wiki text as
+`[{ALLOW <action> <principal>...}]`. The wiki ships its own canonical
+security documentation **on the wiki itself** at
+`https://jspwiki-wiki.apache.org/Wiki.jsp?page=Security` (and its CVE log at
+`?page=CVE`); these pages were not fetched into this draft (§14 Q1) so the
+PMC should expect to compare this document against them.
+
+## §2 Scope and intended use
+
+### Intended use
+
+- A **multi-user collaborative-editing wiki**, deployed by an operator inside
+  a servlet container, accessed by end users over HTTP/HTTPS — most commonly
+  for documentation, knowledge base, or intranet collaboration *(documented:
+  `README.md`, `jspwiki-main/src/main/resources/ini/jspwiki.properties`
+  lines 31–36)*.
+- **Multi-tenancy is "soft"**: a single JSPWiki deployment serves a single
+  logical wiki (the `jspwiki.applicationName`); cross-wiki isolation is not a
+  property the engine claims *(inferred — §14 Q2)*. The wildcard wiki-prefix
+  syntax in `PagePermission` (`*:PageName`) is a permission scope, not a
+  tenancy boundary.
+- **The wiki content is itself trusted to express security policy**: ACL
+  directives, `[{ALLOW edit Charlie}]`, are wiki-text constructs parsed out
+  of page content by `DefaultAclManager` (regex
+  `\[\{\s*ALLOW\s+...\}\]` —
+  `jspwiki-main/src/main/java/org/apache/wiki/auth/acl/DefaultAclManager.java`
+  line 73). An attacker who can edit a page can rewrite that page's ACL *if
+  and only if* the existing ACL grants them `edit` *(documented: same file)*.
+
+### Deployment shape — three supported postures
+
+JSPWiki is **always** a servlet-container-hosted webapp; there is no
+embedded/library mode. Within that shape there are three deployment
+postures with materially different threat envelopes — call them P1, P2, P3:
+
+| Posture | Authentication source | Anonymous can edit? | Notes |
+| --- | --- | --- | --- |
+| **P1 — Open intranet wiki** | Cookie-asserted identity, or JSPWiki 
UserDatabase | yes, by default *(documented: `jspwiki.policy` "Anonymous" block 
lines 68–71 grants `modify` and `createPages` to `Role "Anonymous"`)* | This is 
the "Internet-facing wikis, you are strongly advised to remove the lines 
containing the 'modify' and 'createPages' permissions" warning in 
`jspwiki.policy` line 60. Out-of-box default. |
+| **P2 — Custom auth via JAAS UserDatabase** | `jspwiki.loginModule.class` 
(default `UserDatabaseLoginModule`; XML or JDBC) | configurable | The 
mainstream production posture; the engine's own form-based login screen, 
throttled per `jspwiki.login.throttling=true`. |
+| **P3 — Container-managed authentication** | Servlet container (Tomcat, etc.) 
via `web.xml` `<security-constraint>` + JAAS realm | configurable | Operator 
uncomments the relevant `<security-constraint>` blocks in `WEB-INF/web.xml` 
(lines noted in the shipped file: "REMOVE ME TO ENABLE CONTAINER-MANAGED 
AUTH"). |
+
+A finding is in-model only if it cleanly applies under at least one of
+these postures (with the posture identified). A finding that requires P1 +
+the explicit guideline warning being ignored is `OUT-OF-MODEL:
+non-default-build` against the operator, **not** a JSPWiki bug
+*(inferred — §14 Q3)*.
+
+### Caller roles (per output-structure §2, network-service split)
+
+| Role | Trust level | Notes |
+| --- | --- | --- |
+| **Anonymous network peer** | untrusted | TCP/HTTP to the wiki's port; 
identity Role `Anonymous` *(documented: `Role.java` line 39)*; permissions are 
whatever the local `jspwiki.policy` grants `Role "Anonymous"` |
+| **Asserted user** | untrusted-but-named | Identity asserted by a 
self-supplied cookie; Role `Asserted` *(documented: `Role.java` line 42, 
`jspwiki.properties` `jspwiki.cookieAssertions`)*. JSPWiki's own docs label 
this "still considered to be unsafe, just like no login at all" *(documented: 
`jspwiki.properties` lines 547–553)* |
+| **Authenticated end user** | low-trust | Authenticated via P2 form login or 
P3 container login; Role `Authenticated` *(documented: `Role.java` line 45)* |
+| **Group member** | low-trust + group privileges | Member of a wiki-managed 
`Group` (`GroupPrincipal`) defined by other Authenticated users *(documented: 
`jspwiki.properties` `jspwiki.groupdatabase`, `Group.java`)* |
+| **Container-defined role** | configurable | Roles surfaced by 
`WebContainerAuthorizer.isUserInRole()` via `web.xml` `<security-role>` 
*(documented: `AuthenticationManager.java` lines 84–90)* |
+| **Admin** | trusted within wiki | Member of the wiki `Admin` group **or** of 
container role `Admin`; granted `AllPermission` by default `jspwiki.policy` 
lines 107–112 |
+| **Operator** | fully trusted | Has filesystem access to 
`jspwiki[-custom].properties`, `jspwiki.policy`, the page-store directory, the 
user/group XML databases, the cookie-login store under 
`$jspwiki.workDir/logincookies`, container deployment, and the JVM |
+| **Plugin / page-filter author** | fully trusted | Plugins run **in-process 
inside the wiki webapp**; see Component-family table below |
+| **PageFilter chain (SpamFilter etc.)** | trusted code, untrusted input | 
Operates on wiki-text on save; same in-process trust as the engine |
+
+### Component-family table
+
+| Family | Representative entry | Touches outside the process? | In this 
model? |
+| --- | --- | --- | --- |
+| **JSPWiki markup parser** (default) — `JSPWikiMarkupParser` *(documented: 
`MarkupParser.java` line 74)* | wiki text → XHTML | no | yes |
+| **Markdown parser** (optional) — switched via `jspwiki.syntax=markdown` 
*(documented: `jspwiki.properties` line 476–478)* | wiki text → XHTML | no | 
yes |
+| **Plugin subsystem** — `DefaultPluginManager` *(documented: 
`DefaultPluginManager.java`)* | `[{INSERT FunnyPlugin foo='bar'}]` runs 
arbitrary Java in-process | runs operator-/admin-permitted Java code | yes; 
admission is the engine's job, plugin behaviour is **out of model** for the 
plugin author's code |
+| **External plugin JARs** — `jspwiki.plugin.externalJars` *(documented: 
`jspwiki.properties` lines 401–405)* | added to classpath at runtime | reads 
operator-configured JAR paths | yes for the loading mechanism; **out of model** 
for the loaded code itself *(see §3)* |
+| **Page-filter chain** (`PageFilter`/`BasePageFilter`) — runs on save/load | 
wiki text in-flight | no | yes |
+| **SpamFilter / Akismet integration** *(documented: `SpamFilter.java`)* | 
egress HTTPS to Akismet when configured | outbound HTTPS | in-model for 
credential handling; **out of model** for Akismet's behaviour |
+| **AttachmentServlet** *(documented: `AttachmentServlet.java`)* | HTTP `POST` 
multipart upload, `GET` download | filesystem (`BasicAttachmentProvider` 
storage dir) | yes |
+| **`BasicAttachmentProvider`** + alternative providers | storage of 
attachment bytes | filesystem | yes |
+| **Page store providers** (`FileSystemProvider`, `VersioningFileProvider`, 
JDBC, …) | persistence of wiki text | filesystem or JDBC | yes |
+| **AuthenticationManager + JAAS LoginModules** (`UserDatabaseLoginModule`, 
`WebContainerLoginModule`, `CookieAssertionLoginModule`, 
`CookieAuthenticationLoginModule`, `AnonymousLoginModule`) *(documented: 
`auth/login/`)* | credential check | reads user database, optionally cookie 
store | yes |
+| **AuthorizationManager** + JAAS `Policy` *(documented: 
`AuthorizationManager.java`, `jspwiki.policy`)* | `checkPermission(Session, 
Permission)` | no | yes |
+| **DefaultAclManager** — inline `[{ALLOW ...}]` directive parsing 
*(documented: `DefaultAclManager.java`)* | reads wiki text | no | yes |
+| **WikiSession / SessionMonitor** | servlet `HttpSession` + JAAS `Subject` | 
no | yes |
+| **Install.jsp + admin/SecurityConfig.jsp** | first-run setup + ongoing 
security audit UI *(documented: `Installer.java`, `SecurityVerifier.java`)* | 
reads/writes policy, user DB | yes |
+| **Boot-time `SecurityVerificationUtility`** — runs at startup, optionally 
emails admins on misconfiguration *(documented: 
`SecurityVerificationUtility.java`)* | sends mail | yes (SMTP) | yes |
+| **AuditLogger** *(documented: `org.apache.wiki.security.AuditLogger`, 
`jspwiki.properties` `audit.enabled=true`)* | structured security events | 
optionally outbound mail (`audit.alert.to`) | yes |
+| **External login backends (LDAP/Keycloak)** *(documented: 
`jspwiki.properties` lines 1112–1115 — "container managed scenarios does not 
apply here, nor does external configurations, like keycloak")* | delegated via 
JAAS | network egress | in-model for credential / role-mapping handling; **out 
of model** for the IdP itself |
+| **Markdown WYSIWYG editor** *(documented: `jspwiki-wysiwyg`)* | HTML ↔ wiki 
syntax converter | no | yes |
+| **WebDAV support** | HTTP — separate URL pattern | no | **conditionally in 
model**: `ReleaseNotes` line 394 states "WebDAV does not yet support the new 
authentication/permissions scheme. Therefore, if you have very sensitive data 
in your wiki, you might not want to enable it." → **OUT OF MODEL** for 
production security unless the PMC overrides *(inferred — §14 Q4)* |
+| **XML-RPC interface** (`jspwiki-xmlrpc/`) | alternative wire protocol | no | 
in-model if shipped enabled *(inferred — §14 Q5)* |
+| **Examples / portable / docker-files / it-tests / wikipages** 
(`jspwiki-portable`, `jspwiki-it-tests`, `docker-files/`, `jspwiki-wikipages`) 
| tooling and seed content | varies | **out of model** *(§3 item 7)* |
+| **210/211 legacy templates and the 2.10 adapters** (`jspwiki-210-adapters`, 
`jspwiki-210-test-adaptees`, legacy template dirs) | backward-compat code | n/a 
| in-model only for currently-supported entry points *(inferred — §14 Q6)* |
+
+A finding is in-model only if it lands in a row marked "yes". The plugin /
+filter / Markdown WYSIWYG rows are all "in-process inside the wiki webapp"
+— they share the wiki's authority entirely, which materially shapes §3,
+§7, and §9.
+
+## §3 Out of scope (explicit non-goals)
+
+JSPWiki is not, and does not aim to be, the following — reports requiring
+any of these will be closed with the cited disposition:
+
+1. **A defender against the operator.** Anyone with filesystem access to
+   `jspwiki[-custom].properties`, `WEB-INF/jspwiki.policy`, the page
+   storage directory, the user/group XML databases, the cookie-login store
+   under `$jspwiki.workDir/logincookies`, the servlet container's
+   `conf/`/`webapps/`, or the JVM itself has unbounded authority over the
+   wiki. "The operator misconfigured X" is not a JSPWiki vulnerability
+   *(documented: `jspwiki.properties` `logincookies` warning lines 562–566;
+   inferred — §14 Q7)*. → `OUT-OF-MODEL: adversary-not-in-scope`.
+2. **A defender against the wiki Admin.** Anyone in the wiki `Admin` group or
+   the container `Admin` role is granted `AllPermission` by default
+   *(documented: `jspwiki.policy` lines 107–112)* and can also create
+   wiki pages, install plugins via uploaded attachments (under appropriate
+   permissions), and edit ACLs on any page. They are part of the wiki's TCB.
+   *(inferred — §14 Q7)*. → `OUT-OF-MODEL: adversary-not-in-scope`.
+3. **A sandbox for plugins, page-filters, page providers, attachment
+   providers, search providers, syntax decorators, user/group databases, or
+   any other operator-installed or admin-installed Java module.** All of
+   these run in-process with the JSPWiki webapp's privileges. Admission to
+   the classpath is the operator's call (default search package
+   `org.apache.wiki.plugin`, plus `jspwiki.plugin.searchPath`, plus
+   `jspwiki.plugin.externalJars`). Once admitted, the plugin has the full
+   Java authority of the webapp *(documented: `DefaultPluginManager.java`,
+   `jspwiki.properties` lines 376–405; inferred — §14 Q8)*. →
+   `BY-DESIGN: property-disclaimed` (§9).
+4. **A SecurityManager-based sandbox for wiki content.** Although JSPWiki's
+   authorization model is built on Java 2 permissions (`PagePermission`,
+   `WikiPermission`, `AllPermission`) and the AuthorizationManager javadoc
+   describes it using `AccessController#checkPermission`, the
+   `ReleaseNotes` line 410 states "Running with a security manager isn't
+   yet supported (see JSPWIKI-129)". This means: the policy file
+   `WEB-INF/jspwiki.policy` is read and enforced **by JSPWiki's own
+   AuthorizationManager** for wiki-level permissions, **not** by a JVM
+   `SecurityManager` for general Java permissions. There is therefore no
+   defence against a plugin that simply calls
+   `System.exec("rm -rf /")` — and on JDK 17+ this defence is anyway

Review Comment:
   `System.exec(...)` is not a valid Java API, which makes this example 
technically inaccurate. Consider replacing it with a correct Java process-spawn 
example (e.g., via `Runtime`/`ProcessBuilder`) to avoid confusing readers and 
to keep the threat model precise.



##########
draft-THREAT-MODEL.md:
##########
@@ -0,0 +1,1243 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0

Review Comment:
   Use the HTTPS form of the Apache License URL 
(`https://www.apache.org/licenses/LICENSE-2.0`) to avoid embedding an HTTP link 
in security documentation.



##########
draft-THREAT-MODEL.md:
##########
@@ -0,0 +1,1243 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# Apache JSPWiki Security Threat Model (draft)
+
+## §1 Header
+
+- **Project**: Apache JSPWiki — a Java/JSP wiki engine packaged as a servlet
+  webapp (WAR), deployed inside an operator-supplied servlet container
+  (Apache Tomcat 10.1+ recommended) on JDK 17+ *(documented: `README.md`)*.
+- **Repository scope**: `apache/jspwiki` only. `jspwiki-site` and
+  `jspwiki-asf-docs` are dormant and **out of scope** (confirmed by PMC chair
+  Juan Pablo Santos, 2026-05-30).
+- **Version / commit**: drafted against the default branch (`master`),
+  HEAD `be4ed49` ("use full artifact for javadocs doclet", 2026-05-28),
+  corresponding to development series `3.0.0-git-23`. A report against
+  released JSPWiki version *N* should be triaged against the model as it
+  stood at *N*, not at HEAD.
+- **Date**: 2026-05-30.
+- **Authors**: ASF Security team draft, awaiting JSPWiki PMC review.
+- **Status**: draft — under maintainer review.
+- **Reporting**: vulnerabilities that fall under §8 (claimed properties)
+  should be reported per the Apache Security Team disclosure channel
+  (<[email protected]>); reports that fall under §3 (out of
+  scope), §9 (properties not provided), or §11a (known non-findings)
+  will be closed by JSPWiki triagers citing this document. JSPWiki
+  additionally maintains a public CVE log at
+  `https://jspwiki-wiki.apache.org/Wiki.jsp?page=CVE` *(maintainer-published
+  artefact — not mined into this draft, see §14 Q1)*.
+- **Provenance legend** —
+  *(documented)* = drawn from in-repo docs, code, or website docs, with
+  citation;
+  *(maintainer)* = stated by a JSPWiki maintainer in response to this draft;
+  *(inferred)* = synthesized by the producer from code structure or domain
+  knowledge, awaiting PMC ratification (every *(inferred)* tag has a matching
+  §14 question).
+- **Draft confidence**: 38 documented / 1 maintainer / 27 inferred.
+
+JSPWiki is a long-lived wiki engine (origins in 2001) whose core abstractions
+are: a **WikiSession** (a long-running per-HTTP-session principal/Subject
+construct, see `org.apache.wiki.api.core.Session`); a **Engine** (process-
+global, holds page/attachment providers, plugin manager, authn/authz
+managers); a **markup parser** that translates JSPWiki syntax (or, optionally,
+Markdown) into XHTML; a **plugin/page-filter** subsystem that runs Java code
+inline as wiki pages are rendered or saved; and a JAAS-based AAA stack
+layered on top of either the servlet container's authentication or JSPWiki's
+own UserDatabase. Authorization is expressed as **Java 2-style permissions**
+(`PagePermission`, `WikiPermission`, `GroupPermission`, `AllPermission`)
+matched against a `WEB-INF/jspwiki.policy` security-policy file *and*, on a
+per-page basis, an inline **ACL** embedded in the wiki text as
+`[{ALLOW <action> <principal>...}]`. The wiki ships its own canonical
+security documentation **on the wiki itself** at
+`https://jspwiki-wiki.apache.org/Wiki.jsp?page=Security` (and its CVE log at
+`?page=CVE`); these pages were not fetched into this draft (§14 Q1) so the
+PMC should expect to compare this document against them.
+
+## §2 Scope and intended use
+
+### Intended use
+
+- A **multi-user collaborative-editing wiki**, deployed by an operator inside
+  a servlet container, accessed by end users over HTTP/HTTPS — most commonly
+  for documentation, knowledge base, or intranet collaboration *(documented:
+  `README.md`, `jspwiki-main/src/main/resources/ini/jspwiki.properties`
+  lines 31–36)*.
+- **Multi-tenancy is "soft"**: a single JSPWiki deployment serves a single
+  logical wiki (the `jspwiki.applicationName`); cross-wiki isolation is not a
+  property the engine claims *(inferred — §14 Q2)*. The wildcard wiki-prefix
+  syntax in `PagePermission` (`*:PageName`) is a permission scope, not a
+  tenancy boundary.
+- **The wiki content is itself trusted to express security policy**: ACL
+  directives, `[{ALLOW edit Charlie}]`, are wiki-text constructs parsed out
+  of page content by `DefaultAclManager` (regex
+  `\[\{\s*ALLOW\s+...\}\]` —
+  `jspwiki-main/src/main/java/org/apache/wiki/auth/acl/DefaultAclManager.java`
+  line 73). An attacker who can edit a page can rewrite that page's ACL *if
+  and only if* the existing ACL grants them `edit` *(documented: same file)*.
+
+### Deployment shape — three supported postures
+
+JSPWiki is **always** a servlet-container-hosted webapp; there is no
+embedded/library mode. Within that shape there are three deployment
+postures with materially different threat envelopes — call them P1, P2, P3:
+
+| Posture | Authentication source | Anonymous can edit? | Notes |
+| --- | --- | --- | --- |
+| **P1 — Open intranet wiki** | Cookie-asserted identity, or JSPWiki 
UserDatabase | yes, by default *(documented: `jspwiki.policy` "Anonymous" block 
lines 68–71 grants `modify` and `createPages` to `Role "Anonymous"`)* | This is 
the "Internet-facing wikis, you are strongly advised to remove the lines 
containing the 'modify' and 'createPages' permissions" warning in 
`jspwiki.policy` line 60. Out-of-box default. |
+| **P2 — Custom auth via JAAS UserDatabase** | `jspwiki.loginModule.class` 
(default `UserDatabaseLoginModule`; XML or JDBC) | configurable | The 
mainstream production posture; the engine's own form-based login screen, 
throttled per `jspwiki.login.throttling=true`. |
+| **P3 — Container-managed authentication** | Servlet container (Tomcat, etc.) 
via `web.xml` `<security-constraint>` + JAAS realm | configurable | Operator 
uncomments the relevant `<security-constraint>` blocks in `WEB-INF/web.xml` 
(lines noted in the shipped file: "REMOVE ME TO ENABLE CONTAINER-MANAGED 
AUTH"). |
+
+A finding is in-model only if it cleanly applies under at least one of
+these postures (with the posture identified). A finding that requires P1 +
+the explicit guideline warning being ignored is `OUT-OF-MODEL:
+non-default-build` against the operator, **not** a JSPWiki bug
+*(inferred — §14 Q3)*.
+
+### Caller roles (per output-structure §2, network-service split)
+
+| Role | Trust level | Notes |
+| --- | --- | --- |
+| **Anonymous network peer** | untrusted | TCP/HTTP to the wiki's port; 
identity Role `Anonymous` *(documented: `Role.java` line 39)*; permissions are 
whatever the local `jspwiki.policy` grants `Role "Anonymous"` |
+| **Asserted user** | untrusted-but-named | Identity asserted by a 
self-supplied cookie; Role `Asserted` *(documented: `Role.java` line 42, 
`jspwiki.properties` `jspwiki.cookieAssertions`)*. JSPWiki's own docs label 
this "still considered to be unsafe, just like no login at all" *(documented: 
`jspwiki.properties` lines 547–553)* |
+| **Authenticated end user** | low-trust | Authenticated via P2 form login or 
P3 container login; Role `Authenticated` *(documented: `Role.java` line 45)* |
+| **Group member** | low-trust + group privileges | Member of a wiki-managed 
`Group` (`GroupPrincipal`) defined by other Authenticated users *(documented: 
`jspwiki.properties` `jspwiki.groupdatabase`, `Group.java`)* |
+| **Container-defined role** | configurable | Roles surfaced by 
`WebContainerAuthorizer.isUserInRole()` via `web.xml` `<security-role>` 
*(documented: `AuthenticationManager.java` lines 84–90)* |
+| **Admin** | trusted within wiki | Member of the wiki `Admin` group **or** of 
container role `Admin`; granted `AllPermission` by default `jspwiki.policy` 
lines 107–112 |
+| **Operator** | fully trusted | Has filesystem access to 
`jspwiki[-custom].properties`, `jspwiki.policy`, the page-store directory, the 
user/group XML databases, the cookie-login store under 
`$jspwiki.workDir/logincookies`, container deployment, and the JVM |
+| **Plugin / page-filter author** | fully trusted | Plugins run **in-process 
inside the wiki webapp**; see Component-family table below |
+| **PageFilter chain (SpamFilter etc.)** | trusted code, untrusted input | 
Operates on wiki-text on save; same in-process trust as the engine |
+
+### Component-family table
+
+| Family | Representative entry | Touches outside the process? | In this 
model? |
+| --- | --- | --- | --- |
+| **JSPWiki markup parser** (default) — `JSPWikiMarkupParser` *(documented: 
`MarkupParser.java` line 74)* | wiki text → XHTML | no | yes |
+| **Markdown parser** (optional) — switched via `jspwiki.syntax=markdown` 
*(documented: `jspwiki.properties` line 476–478)* | wiki text → XHTML | no | 
yes |
+| **Plugin subsystem** — `DefaultPluginManager` *(documented: 
`DefaultPluginManager.java`)* | `[{INSERT FunnyPlugin foo='bar'}]` runs 
arbitrary Java in-process | runs operator-/admin-permitted Java code | yes; 
admission is the engine's job, plugin behaviour is **out of model** for the 
plugin author's code |
+| **External plugin JARs** — `jspwiki.plugin.externalJars` *(documented: 
`jspwiki.properties` lines 401–405)* | added to classpath at runtime | reads 
operator-configured JAR paths | yes for the loading mechanism; **out of model** 
for the loaded code itself *(see §3)* |
+| **Page-filter chain** (`PageFilter`/`BasePageFilter`) — runs on save/load | 
wiki text in-flight | no | yes |
+| **SpamFilter / Akismet integration** *(documented: `SpamFilter.java`)* | 
egress HTTPS to Akismet when configured | outbound HTTPS | in-model for 
credential handling; **out of model** for Akismet's behaviour |
+| **AttachmentServlet** *(documented: `AttachmentServlet.java`)* | HTTP `POST` 
multipart upload, `GET` download | filesystem (`BasicAttachmentProvider` 
storage dir) | yes |
+| **`BasicAttachmentProvider`** + alternative providers | storage of 
attachment bytes | filesystem | yes |
+| **Page store providers** (`FileSystemProvider`, `VersioningFileProvider`, 
JDBC, …) | persistence of wiki text | filesystem or JDBC | yes |
+| **AuthenticationManager + JAAS LoginModules** (`UserDatabaseLoginModule`, 
`WebContainerLoginModule`, `CookieAssertionLoginModule`, 
`CookieAuthenticationLoginModule`, `AnonymousLoginModule`) *(documented: 
`auth/login/`)* | credential check | reads user database, optionally cookie 
store | yes |
+| **AuthorizationManager** + JAAS `Policy` *(documented: 
`AuthorizationManager.java`, `jspwiki.policy`)* | `checkPermission(Session, 
Permission)` | no | yes |
+| **DefaultAclManager** — inline `[{ALLOW ...}]` directive parsing 
*(documented: `DefaultAclManager.java`)* | reads wiki text | no | yes |
+| **WikiSession / SessionMonitor** | servlet `HttpSession` + JAAS `Subject` | 
no | yes |
+| **Install.jsp + admin/SecurityConfig.jsp** | first-run setup + ongoing 
security audit UI *(documented: `Installer.java`, `SecurityVerifier.java`)* | 
reads/writes policy, user DB | yes |
+| **Boot-time `SecurityVerificationUtility`** — runs at startup, optionally 
emails admins on misconfiguration *(documented: 
`SecurityVerificationUtility.java`)* | sends mail | yes (SMTP) | yes |
+| **AuditLogger** *(documented: `org.apache.wiki.security.AuditLogger`, 
`jspwiki.properties` `audit.enabled=true`)* | structured security events | 
optionally outbound mail (`audit.alert.to`) | yes |
+| **External login backends (LDAP/Keycloak)** *(documented: 
`jspwiki.properties` lines 1112–1115 — "container managed scenarios does not 
apply here, nor does external configurations, like keycloak")* | delegated via 
JAAS | network egress | in-model for credential / role-mapping handling; **out 
of model** for the IdP itself |
+| **Markdown WYSIWYG editor** *(documented: `jspwiki-wysiwyg`)* | HTML ↔ wiki 
syntax converter | no | yes |
+| **WebDAV support** | HTTP — separate URL pattern | no | **conditionally in 
model**: `ReleaseNotes` line 394 states "WebDAV does not yet support the new 
authentication/permissions scheme. Therefore, if you have very sensitive data 
in your wiki, you might not want to enable it." → **OUT OF MODEL** for 
production security unless the PMC overrides *(inferred — §14 Q4)* |
+| **XML-RPC interface** (`jspwiki-xmlrpc/`) | alternative wire protocol | no | 
in-model if shipped enabled *(inferred — §14 Q5)* |
+| **Examples / portable / docker-files / it-tests / wikipages** 
(`jspwiki-portable`, `jspwiki-it-tests`, `docker-files/`, `jspwiki-wikipages`) 
| tooling and seed content | varies | **out of model** *(§3 item 7)* |
+| **210/211 legacy templates and the 2.10 adapters** (`jspwiki-210-adapters`, 
`jspwiki-210-test-adaptees`, legacy template dirs) | backward-compat code | n/a 
| in-model only for currently-supported entry points *(inferred — §14 Q6)* |
+
+A finding is in-model only if it lands in a row marked "yes". The plugin /
+filter / Markdown WYSIWYG rows are all "in-process inside the wiki webapp"
+— they share the wiki's authority entirely, which materially shapes §3,
+§7, and §9.
+
+## §3 Out of scope (explicit non-goals)
+
+JSPWiki is not, and does not aim to be, the following — reports requiring
+any of these will be closed with the cited disposition:
+
+1. **A defender against the operator.** Anyone with filesystem access to
+   `jspwiki[-custom].properties`, `WEB-INF/jspwiki.policy`, the page
+   storage directory, the user/group XML databases, the cookie-login store
+   under `$jspwiki.workDir/logincookies`, the servlet container's
+   `conf/`/`webapps/`, or the JVM itself has unbounded authority over the
+   wiki. "The operator misconfigured X" is not a JSPWiki vulnerability
+   *(documented: `jspwiki.properties` `logincookies` warning lines 562–566;
+   inferred — §14 Q7)*. → `OUT-OF-MODEL: adversary-not-in-scope`.
+2. **A defender against the wiki Admin.** Anyone in the wiki `Admin` group or
+   the container `Admin` role is granted `AllPermission` by default
+   *(documented: `jspwiki.policy` lines 107–112)* and can also create
+   wiki pages, install plugins via uploaded attachments (under appropriate
+   permissions), and edit ACLs on any page. They are part of the wiki's TCB.
+   *(inferred — §14 Q7)*. → `OUT-OF-MODEL: adversary-not-in-scope`.
+3. **A sandbox for plugins, page-filters, page providers, attachment
+   providers, search providers, syntax decorators, user/group databases, or
+   any other operator-installed or admin-installed Java module.** All of
+   these run in-process with the JSPWiki webapp's privileges. Admission to
+   the classpath is the operator's call (default search package
+   `org.apache.wiki.plugin`, plus `jspwiki.plugin.searchPath`, plus
+   `jspwiki.plugin.externalJars`). Once admitted, the plugin has the full
+   Java authority of the webapp *(documented: `DefaultPluginManager.java`,
+   `jspwiki.properties` lines 376–405; inferred — §14 Q8)*. →
+   `BY-DESIGN: property-disclaimed` (§9).
+4. **A SecurityManager-based sandbox for wiki content.** Although JSPWiki's
+   authorization model is built on Java 2 permissions (`PagePermission`,
+   `WikiPermission`, `AllPermission`) and the AuthorizationManager javadoc
+   describes it using `AccessController#checkPermission`, the
+   `ReleaseNotes` line 410 states "Running with a security manager isn't
+   yet supported (see JSPWIKI-129)". This means: the policy file
+   `WEB-INF/jspwiki.policy` is read and enforced **by JSPWiki's own
+   AuthorizationManager** for wiki-level permissions, **not** by a JVM
+   `SecurityManager` for general Java permissions. There is therefore no
+   defence against a plugin that simply calls
+   `System.exec("rm -rf /")` — and on JDK 17+ this defence is anyway
+   unavailable from the JVM *(documented: `ReleaseNotes` line 410,
+   `AuthorizationManager.java` lines 95–99 "If security not set to JAAS,
+   will return true"; inferred — §14 Q9)*. → `BY-DESIGN: property-disclaimed`
+   (§9). **This is a high-priority §14 question to confirm.**
+5. **A defender against an authorized editor of a page changing that
+   page's ACL.** An ACL is embedded in the wiki text as `[{ALLOW ...}]`.
+   By construction, anyone who has `edit` on a page can rewrite the ACL —
+   that is the wiki's editorial model, not a privilege-escalation bug
+   *(documented: `DefaultAclManager.java` lines 73, 174–176)*. → `BY-DESIGN:
+   property-disclaimed`.
+6. **A defender against malformed-but-parseable wiki text or Markdown.**
+   The markup parser is robust against malformed input in the sense that
+   it should not corrupt JVM memory or escalate trust, but rendering
+   slow paths, infinite loops, exception-throwing pages, or OOM on
+   pathological input are robustness work, not security issues, unless
+   they cross a trust boundary *(inferred — §14 Q10)*. → `VALID-HARDENING`
+   at most.
+7. **Code that ships but is not part of the supported product:**
+   `jspwiki-it-tests/`, `jspwiki-portable/`, `docker-files/`, `Dockerfile`,
+   `jspwiki-bootstrap/` (build tooling), `jspwiki-bom/` (BOM only),
+   `jspwiki-wikipages/` (seed content), test resources under any module's
+   `src/test/`, the 2.10/211 legacy templates and adapters
+   (`jspwiki-210-adapters`, `jspwiki-210-test-adaptees`) when not the
+   selected `jspwiki.templateDir`, `Jenkinsfile`, and `mvn_cheat-sheet.md`
+   *(inferred — §14 Q6, Q11)*. → `OUT-OF-MODEL: unsupported-component`.
+8. **WebDAV in any deployment that holds "very sensitive data".** Per the
+   project's own `ReleaseNotes` line 394, WebDAV "does not yet support the
+   new authentication/permissions scheme". JSPWiki ships it for convenience
+   but does not extend its security claims to it *(documented; inferred —
+   §14 Q4)*. → `BY-DESIGN: property-disclaimed`.
+9. **Upstream Java libraries Apache JSPWiki vendors or depends on**
+   (Tomcat, log4j, jdom2, oro, Apache Commons FileUpload, Akismet client,
+   Lucene, Tika, JavaMail, jakarta.* libraries, etc.). Where JSPWiki
+   wraps these, the wrapper boundary is in-model; intrinsic upstream
+   vulnerabilities should be reported upstream *(inferred — §14 Q12)*.
+   → `OUT-OF-MODEL: unsupported-component` (with an upstream pointer).
+10. **The Docker image at Docker Hub** (`apache/jspwiki`). The README
+    explicitly states: *"Docker images are not official ASF releases but
+    provided for convenience. Recommended usage is always to build the
+    source."* *(documented: `README.md` line 118)*. Findings in the Docker
+    overlay (`docker-files/`) are `OUT-OF-MODEL: unsupported-component`.
+11. **The published wiki site** (`jspwiki-wiki.apache.org`) is itself a
+    JSPWiki instance — but a finding that requires logging in to *that*
+    specific deployment with specific privileges is a deployment finding
+    against the ASF infra-run wiki, not against the JSPWiki software
+    *(inferred — §14 Q13)*. → `OUT-OF-MODEL: adversary-not-in-scope`.
+12. **The JSPWiki Site repos** (`jspwiki-site`, `jspwiki-asf-docs`).
+    Dormant; out of scope per the chair's confirmation.
+
+## §4 Trust boundaries and data flow
+
+JSPWiki has at least the following trust transitions; a finding is in-model
+only when it cleanly maps to one of them.
+
+| # | Transition | Authentication | Authorization |
+| --- | --- | --- | --- |
+| B1 | Network peer → wiki HTTP endpoint | Servlet container (P3) or JSPWiki 
form/cookie (P1/P2) — driven by 
`AuthenticationManager.login(HttpServletRequest)` *(documented: 
`AuthenticationManager.java` lines 80–105)* | 
`AuthorizationManager.checkPermission(Session, Permission)` *(documented: 
`AuthorizationManager.java`)* |
+| B2 | Network peer → `AttachmentServlet` `POST` (upload) | same as B1 | 
`PagePermission(att, "upload")` *(documented: `AttachmentServlet.java` line 
589–590)*, plus filename allow/forbid lists *(documented: 
`AttachmentServlet.isTypeAllowed`)*, plus optional `jspwiki.attachment.maxsize` 
|
+| B3 | Network peer → `AttachmentServlet` `GET` (download) | same as B1 | 
`PagePermission(att, "view")` *(documented: `AttachmentServlet.java` line 
209–214)*, plus `Content-Disposition: inline` vs `attachment` per 
`jspwiki.attachment.forceDownload` |
+| B4 | Wiki text → MarkupParser → XHTML | wiki text is fully 
attacker-controlled (any editor's bytes) | `jspwiki.translatorReader.allowHTML` 
(default `false`) is the only switch; the parser HTML-escapes everything else 
*(documented: `MarkupParser.java` line 74, `JSPWikiMarkupParser.java` lines 
141–142, 254–255, 300–301, 425–426)* |
+| B5 | Wiki text → ACL parser (`DefaultAclManager`) | wiki text is 
attacker-controlled, but only by an editor who already has `edit` on the page | 
regex extraction, then `AuthorizationManager.resolvePrincipal()` *(documented: 
`DefaultAclManager.java` lines 73, 174)* |
+| B6 | Wiki text → Plugin invocation (`[{INSERT Plugin ...}]`) | wiki text is 
attacker-controlled | `jspwiki.translatorReader.runPlugins` is the master 
switch *(documented: `MarkupParser.java` line 77)*; admission of *which* plugin 
classes are discoverable is operator config (search path + external JARs); 
per-invocation argument validation is the plugin's responsibility |
+| B7 | Cookie / form credentials → JAAS LoginModule | LoginModule per 
`jspwiki.loginModule.class` (default `UserDatabaseLoginModule` — password 
against XML/JDBC) *(documented: `jspwiki.properties` lines 521–529)*; 
container-managed in P3 | Login is throttled by `AuthenticationManager` with 
exponential delay capped at 20 s *(documented: `AuthenticationManager.java` 
lines 38–48)* |
+| B8 | Cookie-asserted identity → `Asserted` Role | the cookie itself is the 
only credential — JSPWiki's docs label this "still considered to be unsafe, 
just like no login at all" *(documented: `jspwiki.properties` lines 547–553)* | 
per `jspwiki.policy` `Role "Asserted"` block lines 79–83 |
+| B9 | Cookie-authenticated identity → `Authenticated` Role | filesystem 
mapping under `$jspwiki.workDir/logincookies` *(documented: 
`jspwiki.properties` lines 561–566)* | per `jspwiki.policy` `Role 
"Authenticated"` |
+| B10 | Page save → `PageFilter` chain → `SpamFilter` → egress | wiki text in 
flight; SpamFilter optionally calls Akismet | `SpamFilter` may bypass 
authenticated users (`ignoreauthenticated`) or operator-listed groups 
(`jspwiki.filters.spamfilter.allowedgroups`) |
+| B11 | Page save → Page provider → storage | provider is operator-configured 
| filesystem permissions on the page-store dir |
+| B12 | Attachment upload → Attachment provider → storage | as above | 
`jspwiki.attachment.allowed` / `.forbidden` allow/forbid lists; **not enforced 
for users with `AllPermission`** *(documented: `jspwiki.properties` lines 
162–163, 169–173)* |
+| B13 | Operator → `WEB-INF/jspwiki.policy` (security policy file) | 
filesystem permissions on the WAR/lib | reloaded at startup; no live-reload 
defense |
+| B14 | Operator → `jspwiki[-custom].properties` | filesystem permissions on 
container's `lib/` | as above |
+| B15 | Boot → `SecurityVerificationUtility` → optional SMTP email to admins | 
configured by `jspwiki.securitycheck.enableEmailOfBootCheck` + 
`jspwiki.securitycheck.destination` *(documented: `jspwiki.properties` lines 
1183–1187, `SecurityVerificationUtility.java`)* | startup-time check only |
+
+### Reachability preconditions per family
+
+- **Markup parser / Markdown parser**: reachable from any input that becomes
+  wiki text — page save (B11, possibly via attacker-controlled body if
+  `Anonymous` has `edit`), or page render with attacker-influenced query
+  params if any. A flat "the parser produces XHTML that, when fed to a
+  browser, executes JavaScript" finding is in-model **only if**
+  `jspwiki.translatorReader.allowHTML = false` (the default) is set —
+  otherwise it is `OUT-OF-MODEL: non-default-build` against the
+  documented dangerous-option warning *(documented: `jspwiki.properties`
+  lines 239–259, `MarkupParser.java` line 72–74)*.
+- **Plugin invocation**: reachable from any wiki text the parser sees.
+  Findings about *plugin execution* are out of model per §3 item 3
+  (`BY-DESIGN`); findings about the plugin-invocation parser itself
+  (the `[{INSERT ... }]` regex) are in-model.
+- **AttachmentServlet `POST`**: reachable from any caller who can pass
+  the `PagePermission(att, "upload")` check, modulo allow/forbid extension
+  filter and max-size limit. **For users with `AllPermission`, the
+  allow/forbid filter and the maxsize limit are not enforced**
+  *(documented: `jspwiki.properties` lines 162–163, 169–173)*.
+- **AttachmentServlet `GET`**: reachable from any caller who passes
+  `PagePermission(att, "view")`. The `Content-Disposition` header is
+  `inline` by default unless `jspwiki.attachment.forceDownload` matches —
+  the default forced-download list is `.html .htm .js .pdf .svg .xml`
+  *(documented: `jspwiki.properties` line 185)*.
+- **ACL parser**: reachable from any editor of the page (the ACL is wiki
+  text); see §3 item 5 for the equivalent-harm framing.
+- **WikiSession / SessionMonitor**: tied to `HttpSession`; the servlet
+  container manages session-cookie security (`Secure`, `HttpOnly`).
+  JSPWiki sets its own auth cookie with `Secure` + `HttpOnly` when
+  `jspwiki.securecookie=true` (default `true`) *(documented:
+  `jspwiki.properties` lines 668–670)*.
+
+## §5 Assumptions about the environment
+
+- **Java runtime**: JDK 17+ *(documented: `README.md` line 46)*.
+- **Servlet container**: Servlet API 6.0; Tomcat 10.1+ recommended
+  *(documented: `README.md` lines 38–39)*.
+- **Operating system**: any OS supported by the chosen JVM and servlet
+  container; no OS-specific assumptions *(inferred — §14 Q14)*.
+- **Filesystem**: operator-controlled, read+write by the JVM process for
+  page storage, attachment storage, user/group XML DBs, the cookie-login
+  store under `$jspwiki.workDir/logincookies`, lucene index, work dir,
+  and log files. Permissions on these directories are operator-managed
+  *(documented: `jspwiki.properties` lines 91–101, 130–141, 562–566)*.
+- **Network**: operator-controlled; TLS termination is the servlet
+  container's responsibility. The `<security-constraint>` in `web.xml`
+  shipped with the WAR includes a block requesting `CONFIDENTIAL`
+  transport for the whole webapp ("this block will require TLS across
+  all the board" — `web.xml`) *(documented)*.

Review Comment:
   Correct the phrase 'all the board' to 'across the board'.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to