vlsi commented on code in PR #6709: URL: https://github.com/apache/jmeter/pull/6709#discussion_r3344006420
########## THREAT_MODEL.md: ########## @@ -0,0 +1,172 @@ +# Apache JMeter — Threat Model (v0 draft) + +> Built on Apache JMeter's existing security policy at +> <https://jmeter.apache.org/security.html>. That page's "Security Model" +> statements are lifted here verbatim as the *(documented)* core; this +> document adds the threat-model structure around them (adversary model, +> in/out scope, properties, known non-findings, triage dispositions). + +## §1 Header + +- **Project:** Apache JMeter (`apache/jmeter`), `master`, against which this draft was written. +- **Date:** 2026-06-02. **Status:** draft — for Apache JMeter PMC review. **Author:** ASF Security team (drafted via the Scovetta threat-model rubric, building on JMeter's `security.html`), for PMC ratification. +- **Version binding:** versioned with the project; a report against version *N* is triaged against the model as it stood at *N*. +- **Reporting cross-reference:** §8-property violations → report privately per ASF process (`[email protected]` → `[email protected]`); §3/§9 findings are closed citing this document and `security.html`. +- **Provenance legend:** *(documented)* = JMeter's own docs/`security.html`/repo; *(maintainer)* = confirmed by a JMeter PMC member through this process; *(inferred)* = reasoned from architecture, not yet confirmed — each has a matching §14 open question. +- **Coexistence:** this model is a strict superset of `security.html`; nothing there is weakened. `security.html` stays the canonical reporting/policy page and should link here for the expanded model. +- **Draft confidence:** ~10 documented / 0 maintainer / ~26 inferred. +- **What JMeter is:** Apache JMeter is a Java load-/performance-testing tool. A user builds a **test plan** (a `.jmx` file) in the GUI or by hand, then runs it — in the GUI, in non-GUI/CLI mode, or distributed across a controller and remote engines — to drive load at a *system under test* and collect results. Test plans may contain scripting (JSR223/Groovy/BeanShell) and therefore arbitrary code. *(documented — README, security.html)* + +## §2 Scope and intended use + +- **Primary use:** a **user-run tool** — the person running JMeter authors (or obtains) the `.jmx`, points it at a target they are authorised to test, and runs it locally or across machines they control. *(documented — security.html)* +- **The user is the trusted operator.** The central design statement: *"The purpose of JMeter is to execute the workload specified in the input jmx file, which may include arbitrary code"* — so JMeter running the plan it is given is the intended behaviour, not an attack. *(documented — security.html)* +- **Roles** (a tool, but distributed mode introduces a network surface): + - **user/operator** — supplies the `.jmx`, runs JMeter. **Trusted.** *(documented)* + - **distributed remote engine** (`jmeter-server`) — a node that accepts a test plan from a controller over RMI and executes it. A **listening network surface** in distributed mode. *(documented — distributed testing + security-manager guidance)* + - **system under test (SUT)** — the target JMeter sends requests to and whose responses it parses. JMeter is the *client* here. *(inferred)* + +**Component-family table:** + +| Family | Entry point | Touches outside process | In model? | +| --- | --- | --- | --- | +| Test-plan load + execution (GUI / non-GUI) | open/run a `.jmx`; JSR223/Groovy/BeanShell elements | runs arbitrary code **by design** | **In, but see §9 — executing the plan is by-design** *(documented)* | +| Distributed / remote testing | `jmeter-server` RMI controller↔engine | network (listens) | **In — the real network boundary** *(documented)* | +| Protocol client + response processing | HTTP/JDBC/JMS/etc. samplers; XPath/JSON/regex extractors | network (egress to SUT); parses responses | **In — JMeter as a client parsing SUT responses** *(inferred)* | +| Report/results generation | listeners, dashboard | filesystem | **In (parsing result files)** *(inferred)* | +| Plugins / properties / functions | `user.properties`, plugins, `__function` calls | varies | **In core; third-party plugins out** *(inferred)* | +| `examples/`, test resources, demos | — | — | **Out** *(see §3)* | + +## §3 Out of scope (explicit non-goals) + +- **Executing the test plan the user gives it** — including arbitrary scripting in that plan. This is the whole purpose of the tool. A report that "a `.jmx` / JSR223 element can run code" is **not a vulnerability**; it is the documented design. *(documented — security.html)* +- **Isolating untrusted `.jmx` files** — explicitly delegated to the user: *"If you want to use JMeter to evaluate untrusted jmx files, it is up to you to provide the required isolation."* *(documented — security.html)* +- **Attackers who already control the machine JMeter runs on, its `user.properties`, its plugins, or the controller in a distributed run.** Operator-trusted. *(inferred)* +- **The security of the system under test.** JMeter drives load at it; defending the SUT is not JMeter's job. *(inferred)* +- **`examples/`, demo/test resources.** *(inferred)* + +## §4 Trust boundaries and data flow + +- **The `.jmx` is NOT a trust boundary — it is trusted input by design** (§3). The user vouches for the plan they run. *(documented)* +- **The distributed-testing RMI surface IS a trust boundary.** `jmeter-server` accepts a serialized test plan + commands from a controller over RMI; an attacker who can reach that port (or MITM it) without the protections could get the engine to execute a plan — i.e. code execution on the remote host. The documented defense: *"when JMeter is used in distributed environment, we recommend setting up the security manager in order to avoid any execution of malicious code on the distributed architecture"*, plus RMI-over-SSL with keystore/client-auth for the controller↔engine channel. *(documented — security.html + distributed-testing docs; SSL specifics inferred)* +- **The SUT→JMeter response path is a (softer) boundary:** if a user is induced to test a hostile server, that server's responses are parsed by JMeter's extractors (XML/XPath → XXE, regex → ReDoS, large responses → memory). Whether this is in-model depends on how adversarial the SUT is assumed to be (see §14). *(inferred)* +- **Reachability precondition:** a finding is **in-model** if it is reachable (a) by a network party against the distributed-RMI surface under the documented/default protections, or (b) from a malicious SUT's responses (subject to §14), or (c) pre-execution while merely *opening* a file the user did not intend to be executable. Anything that requires the user to run a `.jmx` they chose to run is `OUT-OF-MODEL`/`BY-DESIGN`. *(inferred)* + +## §5 Assumptions about the environment + +- **Runtime:** JVM; runs as a desktop GUI app, a CLI process, or `jmeter-server` remote engine. *(documented — README)* +- **The user controls the host, the `.jmx`, `user.properties`, installed plugins, and (in distributed mode) the controller and engines.** *(inferred)* +- **Java Security Manager** is the documented isolation mechanism for distributed/untrusted-plan scenarios — but note it is the *user's* to configure, and the platform Security Manager is deprecated in modern JDKs (a §14 question on the forward story). *(documented that it is recommended; the deprecation caveat inferred)* +- **Negative side-effects inventory** (inferred — wave-1/2 target): JMeter makes outbound network requests to the SUT by design; in distributed mode it listens for RMI; it reads/writes test plans, results, and properties on the local filesystem; it executes user-supplied scripting. *(inferred)* + +## §5a Build-time and configuration variants + +Security-relevant configuration *(documented unless noted):* + +- **Distributed RMI security** — the controller↔engine channel: RMI-over-SSL with a keystore and client auth (default on in recent versions?), plus the recommended **Security Manager** policy on engines. Confirm the current defaults. *(documented that the security manager is recommended; SSL default inferred)* +- **`jmeter-server` bind / exposure** — what interface the remote engine binds to by default, and whether it requires the SSL keystore to start. *(inferred)* +- **Scripting elements** (JSR223/Groovy/BeanShell, `__groovy`/`__BeanShell` functions) — always available; gated only by who controls the `.jmx` (the user). *(documented design)* + +**Insecure-default check:** if `jmeter-server` ships accepting RMI connections without SSL/auth by default, a report against that default is `VALID`; if SSL/keystore is required by default, an unprotected deployment is `OUT-OF-MODEL: non-default-build`. Wave-1 question (§14). (Cf. CVE-2019-0187, the historical RMI-without-SSL issue.) + +## §6 Assumptions about inputs + +Per-surface trust table *(all inferred unless noted):* + +| Surface | Input | Attacker-controllable? | Caller/operator must enforce | +| --- | --- | --- | --- | +| `.jmx` test plan (open/run) | plan XML + embedded scripts | **no — trusted by design**; **yes only if the user runs an untrusted plan**, which they must isolate | don't open/run untrusted `.jmx` without OS/JVM isolation | +| Distributed RMI (`jmeter-server`) | controller commands + serialized plan | **yes (network), if the channel is unprotected** | RMI-over-SSL + keystore + Security Manager on engines | +| SUT responses | HTTP/JDBC/etc. response bodies | **yes if the SUT is hostile** | test only systems you trust/own, or treat responses as untrusted | +| `user.properties` / plugins | local config | no — operator-trusted | vet plugins | +| Result/JTL files (re-opened) | results to render | **yes if a result file is from an untrusted source** | don't open untrusted result files | + +- **Size/shape/rate:** response/result-file size handling and recursion (XML/regex) bounds are open (see §8). *(inferred)* + +## §7 Adversary model + +- **Distributed-mode network attacker** — can reach a `jmeter-server` RMI port or MITM the controller↔engine link; goal: code execution on a remote engine. The primary in-model adversary. *(documented surface; framing inferred)* +- **Malicious-`.jmx` social-engineering** — tricks a user into *opening/running* a hostile plan. JMeter's stance: this executes by design; isolation is the user's responsibility. So this is an *acknowledged, disclaimed* threat, not a defended one. *(documented — security.html)* +- **Malicious SUT** — a target server returning hostile responses to exploit JMeter's response parsing. In-model only if the PMC assumes the SUT can be adversarial (see §14). *(inferred)* +- **Out of scope:** anyone with control of the JMeter host, the controller, `user.properties`, or installed plugins. *(inferred)* + +## §8 Security properties the project provides + +*(Distributed-mode protection is documented-as-recommended; the guarantees below are for PMC confirmation.)* + +- **Distributed-mode isolation (when configured).** With RMI-over-SSL + keystore/client-auth and the recommended Security Manager, a network party cannot drive a remote engine to execute code. *Violation symptom:* remote code execution on a `jmeter-server` engine by an unauthenticated/MITM network party under the documented protections. *Severity:* security-critical. *(documented that the protections are recommended; that they hold is the claim to confirm)* +- **No unintended code execution from *opening* a non-executed file** — opening a result/JTL file, or loading a `.jmx` into the GUI without running it, should not by itself be a path to code execution *beyond what `security.html` already discloses for `.jmx`*. (security.html says even *opening* a `.jmx` "may in some cases trigger code execution" — so the in-model line is about result files and unexpected triggers.) *Violation symptom:* code execution from opening a file the user did not run. *Severity:* security-critical. *(inferred — needs the PMC to draw this line precisely)* +- **Safe response handling — UNSPECIFIED.** Whether JMeter's extractors are hardened against hostile SUT responses (XXE, ReDoS, decompression/size bombs) is open. *(inferred)* Review Comment: This interferes with "test only systems you trust/own, or treat responses as untrusted" above. If we go for "test only systems you trust/own", then "safe response handling is, well, not a security issue, and it is more like a hardening. @milamberspace , WDYT? Frankly, I am not sure if we would like to open "we consider a vulnerability if a malicious SUT can trick JMeter" box. -- 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]
