- Project: Apache Synapse — a lightweight, high-performance Enterprise Service Bus (ESB) / mediation
engine. It accepts messages over pluggable transports (HTTP/S, JMS, VFS, Mail, …), runs them through
operator-defined mediation sequences / proxy services (mediators: XSLT, XQuery, script, filter,
switch, send-to-endpoint, …), and routes/transforms them toward backend endpoints (documented — README;
source
org.apache.synapse.mediators,config.xml). - Modelled against:
apache/synapsemaster@0b40f4d7d7777d109f167c0b4afa21afbfb10988(2026-06-15), with dependency defaults verified against Axis2 1.7.9 and Axiom 1.2.22 (the versions pinned in the rootpom.xml). - Status: **v1 — source-verified ** Produced by the ASF Security
team via the
threat-model-producerrubric (https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573). Reviewed by the Synapse PMC. - Reporting / version-binding / legend as in the sibling models. Confidence: ~14 documented / 0 maintainer / ~34 source-verified / ~12 inferred.
Framing note (as for any framework): Synapse is a mediation engine, not a finished application. The integration developer authors the synapse configuration — sequences, mediators, scripts, XSLT/XQuery, endpoints, and security policies. That configuration is trusted input (§3); the inbound message from a network client is the untrusted adversary input (§7). Most properties are conditional on how the integration is configured, so §9/§10 carry a lot of weight.
Intended use (documented): deploy Synapse as a message broker/mediator in front of or between services —
clients send messages to a Synapse proxy/API; Synapse mediates (transform, route, secure, throttle) and
forwards to backend endpoints. In message-mediation mode, Synapse additionally acts as a
WS-Addressing-style router: a bare <send/> with no configured endpoint forwards to the message's implicit
To address (source-verified — SendMediator.mediate(); see §9).
Caller roles:
- Message client (untrusted) — any peer that can send a message to a Synapse listener/proxy/API.
- Backend endpoint — a service Synapse calls; semi-trusted (its responses re-enter mediation).
- Integration developer / operator — authors the synapse config (mediation logic, scripts, XSLT, endpoints, secure-vault secrets, transport + WS-Security policy). Trusted; out of model as adversary (§3).
Component-family table:
| Family | Entry point | Touches outside process | In model? |
|---|---|---|---|
| Transport listeners | HTTP/S (NHTTP/passthrough), JMS, VFS, Mail | network / fs / mail | Yes |
| Mediation engine | sequences / proxy services / APIs | — | Yes |
| XML transform mediators | XSLT, XQuery, payload factory | XML; external refs | Yes (high-value) |
| Script mediators | JS/Groovy/… (operator-authored) | runs config code over message data | Yes (data-in surface) |
| Endpoints (outbound) | send/call mediators, address/WSDL/loadbalance | network egress | Yes (SSRF surface) |
| Eventing | WS-Eventing subscriptions | network | Yes |
| Secrets / secure-vault | encrypted config secrets | keystore | Yes |
| Samples / docs / build | modules/documentation, samples, tests |
— | No → §3 |
- The integration developer / operator as adversary, and the synapse configuration itself (sequences,
scripts, XSLT/XQuery bodies, endpoint addresses, secrets). Config is authored by a trusted party; a script
mediator running operator-authored code is not an adversary surface — the message data flowing into it is
(source-verified — config is loaded from operator-controlled
synapse.xml/registry, never from messages). - Misconfiguration (enabling external-entity resolution, routing to an attacker-derived endpoint without validation, disabling TLS) — Synapse provides the controls; using them is the operator's job (§10/§11).
- Backend services Synapse mediates to, and the message producers' own security.
- Samples, documentation, and tests (
modules/samples,modules/documentation,src/testtrees). - The underlying XML/crypto stacks (the JAXP/StAX provider, Rampart/WSS4J) except as Synapse configures
and invokes them. Note however that two dependency defaults are load-bearing for §8 and are therefore
version-bound in §1: Axis2's builder parser configuration and Axiom's
StAXParserConfiguration.SOAP.
The trust boundary is the transport listener + the mediation entry: bytes arriving on a listener are untrusted until mediation (and any configured WS-Security/transport auth) has processed them.
Trust transitions:
- Wire → message build: the transport builds a message (SOAP/XML/JSON/binary).
Source-verified: both the SOAP and the plain-XML (POX) build paths go through Axis2
BuilderUtil.createSOAPModelBuilder/createPOXBuilder, which use AxiomStAXParserConfiguration.SOAP→StAXDialect.disallowDoctypeDecl. A DOCTYPE declaration in an inbound message is rejected outright, which blocks classic XXE and DTD-based entity-expansion (billion-laughs) by default. The passthrough HTTP transport additionally defers building the message body (RelayUtils/DeferredMessageBuilder): the envelope is only parsed when a mediator actually needs it, so pure-routing configurations never parse untrusted bodies at all. There are, however, no built-in message-size or element-depth limits in the NHTTP/passthrough transports (§9). - Message → XSLT/XQuery mediator: the transform input is the already-parsed AXIOM tree, so no DTD/XXE
can be introduced at this stage (blocked at transition 1). The XSLT mediator creates its
TransformerFactorywith JAXP defaults —FEATURE_SECURE_PROCESSINGis not set (source-verified —XSLTMediator); stylesheet functions such asdocument()/doc()(XQuery via Saxon XQJ) therefore remain available. Because the stylesheet/query body is trusted config, this becomes an attacker surface only when the operator's stylesheet feeds message-derived strings intodocument()/doc()or extension functions — an integration responsibility (§9/§10), with a per-mediator hardening knob available (<feature>/<attribute>elements on<xslt>can enable secure-processing — §5a). - Message → script mediator: operator-authored JS/Groovy runs with message data as input. The code is trusted (config); the risk is unsafe handling of message data inside it.
- Message → endpoint resolution: static endpoints are config (trusted). Two attacker-influenced routes
exist: (a) explicit dynamic/content-based routing the integration builds (header/XPath-derived
addresses), and (b) implicit
Torouting —<send/>with no endpoint forwards to the inbound message'sToaddress (source-verified —SendMediator). Both are SSRF surfaces the integration must constrain (§9/§10). - Endpoint response → mediation: backend responses re-enter mediation as semi-trusted input.
Reachability precondition: a finding is in-model if reachable from an inbound message before the
mediation auth/validation the integration configured; a finding requiring a malicious config (script,
XSLT body, endpoint address chosen by the operator) is OUT-OF-MODEL: trusted-input (§3/§6).
- JVM host running the Synapse runtime; operator-managed
synapse.xmlconfig, keystores, and transport setup. - Transports reachable per operator network config; TLS provided by the transport configuration.
- Secrets via secure-vault are protected by an operator-managed keystore/password (source-verified —
org.apache.synapse.securevault: keystore-backed asymmetric/symmetric ciphers;PasswordManagerresolves encrypted passwords at runtime). - What Synapse does to its host: binds transport listeners; opens outbound connections to configured (and possibly message-derived — §4.4) endpoints; reads config + keystores; XSLT/XQuery may fetch external references if the trusted stylesheet requests them. Not assumed to spawn host processes beyond configured command/script mediators.
- Because there are no built-in message-size limits (§9), deployment-level ingress controls (reverse proxy / LB request-size caps, connection limits) are assumed for internet-facing listeners.
| Knob | Effect | Ruling |
|---|---|---|
| Inbound XML DOCTYPE handling | XXE / entity-expansion | Resolved (source-verified): DOCTYPE rejected by default on SOAP and POX build paths (StAXParserConfiguration.SOAP). No supported knob re-enables it per-service; a report reaching XXE through the default build path is VALID. |
<xslt> <feature>/<attribute> elements |
Per-mediator TransformerFactory features (e.g. http://javax.xml.XMLConstants/feature/secure-processing) |
Resolved (source-verified): off by default (JAXP defaults apply); enabling secure-processing is an operator hardening opt-in. |
| Message size / element-depth limits | XML/large-message DoS | Resolved (source-verified): no built-in limits in NHTTP/passthrough. Passthrough streaming + deferred building bound the pure-routing path; parsing paths rely on deployment controls (§5, §10). Documented as a §9 disclaimed property. |
Dynamic / content-based endpoint resolution; implicit To routing via bare <send/> |
SSRF if destination derived from message | Resolved (source-verified): implicit To routing is designed-in for message-mediation mode; no built-in allow-listing. Validation is the integration's job (§9/§10). |
| Transport TLS (HTTPS listener + outbound) | Confidentiality/integrity | Operator (§10). |
| WS-Security (Rampart) on a proxy | Message-level auth/sig/enc | Integration choice. |
| Script-mediator languages enabled | Operator-code surface | Operator config. |
| Entry point | Parameter | Attacker-controllable? | Caller/operator must enforce |
|---|---|---|---|
| transport listener | message body (SOAP/XML/JSON/binary), headers, SOAPAction, To/request URI |
yes | deployment size caps; transport/WS-Security |
| XSLT/XQuery mediator | message payload (the transform input) | yes | don't pass message data into document()/doc()/extensions; optionally enable secure-processing |
| script mediator | message payload passed to the script | yes | safe handling of message data in the script |
dynamic endpoint / bare <send/> |
destination derived from message (To, headers, XPath) |
yes (if configured / message-mediation mode) | validate/allow-list resolved addresses |
| synapse config (sequences, scripts, XSLT, endpoints, secrets) | all | no — operator-trusted | never sourced from a message |
- Primary adversary: an untrusted client sending messages to a Synapse listener/proxy/API. Capabilities:
craft SOAP/XML/JSON payloads (oversized, deeply nested, malformed), supply data that a trusted transform
passes to external resolution, supply a
To/routing value that mediation turns into an outbound destination (SSRF), or data that a script mishandles. (DOCTYPE-based payloads — XXE, billion-laughs — are rejected at the build boundary by default; §4.1.) - Secondary: a malicious backend endpoint returning hostile responses into mediation.
- Goals: SSRF via routing or transform resolution; large-message/streaming DoS; bypass of a configured mediation-level auth; exfiltration of secrets reachable through a transform or log.
- Out of model: the integration developer/operator; the config (scripts, XSLT bodies, endpoint addresses); keystore/secret holders.
- DOCTYPE-free inbound XML parsing. Inbound SOAP and plain-XML messages that contain a Document Type
Declaration are rejected at message-build time; XXE and DTD entity-expansion are therefore not reachable
from the default inbound path (source-verified — Axis2
BuilderUtil+ AxiomStAXParserConfiguration.SOAP, versions pinned in §1). Symptom of violation: an entity defined via DOCTYPE in an inbound message is resolved/expanded on a default build path. Severity: critical. - Robust message building/parsing. Malformed inbound messages yield a fault, not memory corruption;
the passthrough transport streams and defers parsing until a mediator needs the body (source-verified —
RelayUtils/DeferredMessageBuilder). Resource bounding of parsed messages is NOT provided — see §9. Symptom: crash or memory corruption (not mere resource exhaustion) from crafted input. Severity: high. - Trusted-config-only transform code. Stylesheets, XQuery bodies, and script bodies execute only from operator-loaded configuration, never from message content (source-verified — mediator factories read these from config/registry only). Symptom: message content interpreted as stylesheet/query/script code. Severity: critical.
- Mediation-level security mechanisms. When configured, transport security and WS-Security (Rampart) authenticate/sign/encrypt messages (documented; enforcement is Rampart's — see the CXF/WSS4J sibling model for signature-wrapping classes). Symptom: accepted unauthenticated/forged message where policy required otherwise. Severity: critical.
- Secret protection. Secure-vault keeps configured secrets encrypted at rest under a keystore-backed
cipher, resolved to plaintext only in memory at use (source-verified —
org.apache.synapse.securevault). Symptom: plaintext secret in config at rest, or secret emitted to logs by the framework. Severity: high. - Transport security support. TLS on HTTPS listeners and outbound calls with cert validation when configured (documented). Symptom: MITM where TLS expected. Severity: high.
- No security without configuration — a proxy with no transport/WS-Security is only as protected as the integration wired it.
- No built-in message-size / element-depth / entity-count limits (source-verified — none in the
NHTTP/passthrough transports). Bounding oversized or deeply nested messages on parsing paths is a
deployment responsibility (§5, §10). Resource-exhaustion reports against defaults are
BY-DESIGN: property-disclaimed, notVALID, unless they show asymmetric amplification beyond input size. - No defence against the integration developer — scripts, XSLT/XQuery bodies, and endpoint addresses are trusted config (§3).
- No intrinsic SSRF protection for message-derived destinations — this includes both explicit
content-based routing and the designed-in implicit
Torouting of a bare<send/>in message-mediation mode (source-verified —SendMediator). Validating/allow-listing destinations is the integration's job. - No secure-processing on XSLT/XQuery by default —
FEATURE_SECURE_PROCESSINGis not set on theTransformerFactory; operators who pass message data into resolution-capable constructs must enable it per-mediator (§5a) or avoid the construct.
False friends:
- An XSLT/XQuery transform looks like pure data transformation but can read files / fetch URLs via
document()/doc()or extension functions — reachable when the trusted stylesheet feeds message-derived strings into them (the message itself cannot introduce a DTD; §4.1/§4.2). - A script mediator looks sandboxed but runs with the engine's privileges — it is operator code, not a security boundary for message data.
- A bare
<send/>looks like internal plumbing but is a client-steered router — the destination is the inbound message'sTo. - Passthrough streaming looks like a DoS defence, but only for untouched bodies — the moment a mediator reads the payload, the full message is built with no size bound.
Well-known attack classes to keep in view: SSRF via message-derived routing and via transform resolution; oversized-message / deep-nesting DoS on parsing paths; injection into a downstream system via an unsanitized transform; secret exposure through an over-broad transform or log mediator; XML signature-wrapping where WS-Security is used (see the CXF/WSS4J model). (XXE / DTD entity-expansion is default-blocked — §8.1 — and would signal a regression in the §1-pinned builder configuration.)
- Cap request sizes and connection counts at the ingress (LB/reverse proxy) for internet-facing listeners — Synapse does not bound message size (§9).
- Validate or allow-list any destination derived from message content, and avoid bare
<send/>on untrusted traffic unless client-steered routing is intended and network-constrained (anti-SSRF). - Don't feed message-derived strings into
document()/doc()/extension functions in stylesheets and queries; where unavoidable, enable secure-processing on that mediator (§5a) and restrict egress. - Configure transport TLS (with cert validation) and WS-Security where the integration requires authentication/integrity.
- Treat script/XSLT/XQuery mediator bodies as code you own; never accept them from untrusted sources.
- Protect the secure-vault keystore/password; don't commit plaintext secrets; keep secrets out of log mediators.
- Do not downgrade the pinned Axis2/Axiom builder stack or swap in a builder that permits DOCTYPE — §8.1 depends on it.
- Exposing a proxy with no transport/message security and assuming the ESB "is secure".
- A bare
<send/>(or content-derived endpoint) on an internet-facing service with unrestricted egress (SSRF). - Stylesheets/queries that pass message data into
document()/doc()/extension functions. - Internet-facing listeners with no ingress size limits, where sequences build every message body.
- Embedding secrets in plaintext config instead of secure-vault; logging payloads that carry secrets.
- Routing untrusted message content into a script mediator that then executes/concatenates it unsafely.
(Seed list; the PMC owns the authoritative version)
- A script/XSLT/XQuery mediator "executes code" — operator-authored config (§3/§8.3/§9).
- "XXE in Synapse" reproduced only by re-enabling DOCTYPE support (custom builder, modified Axiom/StAX
config, or a non-pinned dependency) —
OUT-OF-MODEL: non-default-build. Against the default build path (§8.1) it would beVALID. - SSRF via an endpoint address the operator configured statically — trusted input (§6).
- SSRF via bare
<send/>/implicitTorouting — designed-in router semantics; disclaimed (§9) →BY-DESIGN: property-disclaimed(constraining it is §10). A report showing it bypasses an explicitly configured endpoint or allow-list would beVALID. - Resource exhaustion from oversized/deeply-nested messages within input-proportional bounds —
disclaimed (§9) →
BY-DESIGN: property-disclaimed. Asymmetric amplification remains in-model under §8.2. - Findings in samples / documentation / tests — out of scope (§3).
- Use of a weak algorithm explicitly configured in a WS-Security policy — integration choice.
XMLInputFactorywithout hardening in config/registry loaders (SynapseConfigUtils,SimpleURLRegistry) — these parse operator-trusted configuration, not messages →OUT-OF-MODEL: trusted-input.
- Any change to the message-build parser configuration (Axis2/Axiom upgrade or replacement) that no longer rejects DOCTYPE by default — invalidates §8.1.
- Introduction of built-in message-size/depth limits — would move that row from §9 to §8.
- A new transport, mediator, or default that resolves untrusted references or derives destinations from messages.
- Setting (or deciding to set)
FEATURE_SECURE_PROCESSINGby default on transform mediators. - A change in secure-vault or WS-Security defaults.
- Any report not cleanly routable to a §13 disposition.
| Disposition | Meaning | Licensed by |
|---|---|---|
VALID |
Violates a claimed property via an in-scope adversary/input in a default config. | §8, §6, §7 |
VALID-HARDENING |
No §8 property broken, but a §11 misuse warrants a safer default/guard. | §11 |
OUT-OF-MODEL: trusted-input |
Requires control of the synapse config (script/XSLT/endpoint/secret). | §6, §3 |
OUT-OF-MODEL: adversary-not-in-scope |
Requires operator/keystore capability. | §7, §3 |
OUT-OF-MODEL: unsupported-component |
Lands in samples/docs/tests. | §3 |
OUT-OF-MODEL: non-default-build |
Only when an insecure non-default parser/builder/resolution option was enabled. | §5a |
BY-DESIGN: property-disclaimed |
Concerns a §9-disclaimed property (size limits; implicit To routing; no security without config; scripts are operator code). |
§9 |
KNOWN-NON-FINDING |
Matches a §11a entry. | §11a |
MODEL-GAP |
Routes to none of the above → revise the model. | §12 |
Deferred; a threat-model.yaml can later encode the §6 trust table, §2/§3 scoping, §8 rows, §9 false
friends, §11a non-findings, and §13 dispositions.