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

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git

commit b5071b4fb55896b135f9d74df01a8308a04d55db
Author: Robert Lazarski <[email protected]>
AuthorDate: Wed Sep 2 18:26:59 2026 -1000

    Write up the 2.0.2 hardening for upgraders
    
    Collect the changed defaults in the release notes with what to set to 
restore
    the previous behaviour, and record content-based dispatch in the threat 
model.
    The existing service-dispatcher row claimed dispatchers only validate 
service
    existence, which understated what late binding allowed.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 SECURITY.md                              | 13 ++++++-
 src/site/markdown/release-notes/2.0.2.md | 67 ++++++++++++++++++++++++++++++--
 2 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/SECURITY.md b/SECURITY.md
index 6b94acc16a..7100641f27 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -136,7 +136,7 @@ Axis2 exposes the following URL patterns from the servlet 
mapping:
 | **JSON-RPC dispatch** | Method name injection; unexpected operation 
invocation | Method names validated against deployed operations; unknown 
methods return fault |
 | **Multipart/file upload** (commons-fileupload2) | Unbounded file count DoS 
(CVE-2023-24998 pattern); unbounded body size; temp-file accumulation | 
commons-fileupload2 enforces the file count limit; `multipartMaxRequestSize` / 
`multipartMaxFileSize` bound the body; temp files are deleted immediately for 
form fields and tracked to collection for file parts |
 | **Form-urlencoded builder** | Unbounded body read into an in-memory map | 
`formUrlEncodedMaxRequestSize` bounds the read; the stream fails rather than 
truncating |
-| **Service dispatchers** | Routing to unintended service; header spoofing | 
Dispatchers validate service existence; unknown services return fault |
+| **Service dispatchers** | Routing to unintended service; header spoofing; a 
service chosen from message content after the Security phase has already run | 
Dispatchers validate service existence and unknown services return fault; 
selecting the service from the SOAP body namespace is off unless 
`allowContentBasedServiceDispatch` is set, so binding happens before the 
Security phase runs |
 | **Hot-deployment** (DeploymentEngine) | Malicious AAR/MAR deploys arbitrary 
code | Trust boundary is filesystem access; no signature verification (admin 
operation) |
 | **Context externalization** (SafeObjectInputStream) | Java deserialization 
gadget chains | Whitelist-based `SafeObjectInputStream`; restricted to known 
Axis2 context classes |
 | **Metadata endpoints** (`?wsdl`, `?xsd`, `/services/`, `.xsd`/`.wsdl` by 
name, OpenAPI/MCP) | Service enumeration, schema disclosure | 
`exposeServiceMetadata` enforced uniformly across the servlet and standalone 
HTTP paths and the OpenAPI/MCP generators |
@@ -320,6 +320,17 @@ migration from `commons-fileupload` 1.x to 
`commons-fileupload2` in
     skipped rather than refused, so it stays indistinguishable from one that
     is not deployed.
 
+13. **Content-based service dispatch (2.0.2):** The inflow phase order is
+    Transport, Addressing, Security, PreDispatch, Dispatch, and `DispatchPhase`
+    installs only the phases that follow it, so a service bound during Dispatch
+    is bound after the Security phase has run against no service and Security 
is
+    never revisited. Selecting a service from the namespace of the SOAP body's
+    first element therefore let a caller whose request URI named no service 
reach
+    a service whose engaged security modules had not run for it.
+    `allowContentBasedServiceDispatch` defaults to `false`. Dispatch by request
+    URI, SOAPAction and WS-Addressing binds the service before the Security 
phase
+    and is unaffected.
+
 ## Reporting Security Issues
 
 Report vulnerabilities to: **[email protected]**
diff --git a/src/site/markdown/release-notes/2.0.2.md 
b/src/site/markdown/release-notes/2.0.2.md
index 9175c9ff8c..4e5a317b9c 100644
--- a/src/site/markdown/release-notes/2.0.2.md
+++ b/src/site/markdown/release-notes/2.0.2.md
@@ -1,4 +1,63 @@
-Apache Axis2 2.0.2 Release Notes
---------------------------------
-
-(Unreleased)
+Apache Axis2 2.0.2 Release Notes
+--------------------------------
+
+(Unreleased)
+
+## Security Hardening
+
+Several defaults changed in this release. Each one closes a surface an
+unauthenticated caller could reach, and each is listed here with what to set 
if a
+deployment genuinely needs the previous behaviour. The full reasoning for each 
is
+in `SECURITY.md`.
+
+- **No default admin console credentials.** The published `axis2-webapp` WAR 
and
+  the `axis2_default.xml` inside `axis2-kernel.jar` shipped `admin`/`axis2` as 
the
+  `/axis2-admin` login. That console can upload services, and so execute code. 
Both
+  now ship empty, which leaves the console disabled: the login rejects empty
+  credentials before comparing, so no request can authenticate until an 
operator
+  sets both `userName` and `password` in their own `axis2.xml`. Deployments 
that
+  relied on the default login must now set one explicitly.
+
+- **Service dispatch from the message body is opt-in.** The inflow order is
+  Transport, Addressing, **Security**, PreDispatch, **Dispatch**, so a service
+  selected during Dispatch is selected after the Security phase has already 
run —
+  against no service, because none was bound yet — and Security is not 
revisited.
+  A request whose URI names no service could therefore pick the service from 
the
+  namespace of the SOAP body's first element, reaching a service whose engaged
+  security modules never ran. `allowContentBasedServiceDispatch` now defaults 
to
+  `false`. Dispatch by request URI, SOAPAction and WS-Addressing is unaffected.
+  Set it to `true` only if services are genuinely addressed by body namespace, 
and
+  not alongside per-service security modules.
+
+- **Decoupled WS-Addressing responses are refused by default.** A non-anonymous
+  `wsa:ReplyTo` or `wsa:FaultTo` makes the server open a connection to an 
address
+  the caller chose. `allowNonAnonymousResponseEndpoints` now defaults to 
`false`;
+  replies and faults travel back down the inbound connection. Deployments that 
use
+  decoupled responses — separate-listener "Dual" clients, or a third-party 
callback
+  endpoint — set it to `true`, and should also set `httpFrontendHostUrl` so the
+  generated reply address is the real external URL. With the feature enabled,
+  `allowedResponseEndpointSchemes` permits HTTPS only, the destination is 
screened
+  at both the header-parsing and transport-selection layers, and redirects are 
not
+  followed.
+
+- **Request bodies are bounded.** The `multipart/form-data` and
+  `application/x-www-form-urlencoded` builders read the transport stream 
directly,
+  so a servlet container's post-size limit never saw the body.
+  `multipartMaxRequestSize` and `multipartMaxFileSize` (100 MB) and
+  `formUrlEncodedMaxRequestSize` (2 MB) now bound them; `-1` restores the 
previous
+  unbounded behaviour, and either may be set per service. The ceilings are 
enforced
+  against bytes actually read, so a chunked body is bounded on the same terms 
as a
+  declared one. Multipart temporary files are deleted rather than accumulating.
+
+- **`exposeServiceMetadata` is honoured uniformly.** Every anonymous metadata 
route
+  now respects it: the `?wsdl`, `?wsdl2` and `?xsd` queries as before, plus the
+  `.xsd`/`.wsdl` file routes on both the servlet and standalone HTTP paths, the
+  named-WSDL route, and the OpenAPI/Swagger/MCP generators. A service with 
exposure
+  disabled is skipped rather than refused, so it stays indistinguishable from 
one
+  that is not deployed.
+
+- **OpenAPI and Swagger UI output.** Request-controlled values are validated 
and
+  encoded for the context they are written into, the served page carries a
+  Content-Security-Policy with a per-response script nonce, and the published
+  `servers[].url` is relative rather than derived from the request Host.
+  `openapi.serverBaseUrl` pins an absolute URL where a deployment needs one.

Reply via email to