Project |
Apache Flume (https://github.com/apache/logging-flume) |
Version/commit |
|
Date |
2026-05-13 |
Author |
Piotr P. Karwasz (Apache Logging Services PMC), draft v0 |
Status |
DRAFT — pre-PMC review |
Reporting |
Findings under §4.8 follow the ASF process at https://www.apache.org/security/. Findings under §4.3 / §4.9 / §4.11a are closed citing this document. |
Provenance |
|
Draft confidence |
~24 documented / 0 maintainer / ~35 inferred (counts approximate; update on each revision) |
Apache Flume is a distributed service for collecting, aggregating, and moving large volumes of event-oriented data (originally log lines) from many agents to centralized stores such as HDFS, HBase, Hive, Kafka, Solr, or ElasticSearch. A Flume agent is a long-running JVM process configured with a topology of sources (which receive events), channels (which buffer them), and sinks (which forward them, often to another agent or to a terminal store). Agents are configured by a properties file and run as a Linux/Windows daemon; they are not embedded in user applications (with the exception of the small embedded agent and log4j appender clients).
This threat model describes the implicit contract between the project and downstream operators: the assumptions Flume makes about its environment and operators, the security properties it provides, the properties it explicitly does not provide, and the misuses that fall outside its intended use. It is not an audit; it does not enumerate bugs or recommend fixes.
- 1. Header and scope context
- 2. Coexistence with existing security documentation
- 3. Component-family table (§4.2)
- 4. Out of scope (§4.3)
- 5. Trust boundaries and data flow (§4.4)
- 6. Environmental assumptions (§4.5)
- 7. Build-time and configuration variants (§4.5a)
- 8. Inputs and trust (§4.6)
- 9. Adversary model (§4.7)
- 10. Security properties Flume provides (§4.8)
- 11. Security properties Flume does not provide (§4.9)
- 12. Downstream responsibilities (§4.10)
- 13. Known misuse patterns (§4.11)
- 14. Known non-findings — recurring false positives (§4.11a)
- 15. Conditions that would change this model (§4.12)
- 16. Triage dispositions (§4.13)
- 17. Open questions for the PMC (§4.14)
- 18. Machine-readable companion (§4.15)
- 19. Self-check status
The Apache Logging Services PMC moved Flume to dormant status on 2024-10-10. The published policy is: bug reports and feature requests are unlikely to be addressed; security reports are addressed; new releases are unlikely. (documented: README.md; logging-flume issue #423; lists.apache.org thread dg9wro6dp7w95o1x911lbyqxzl808b3l)
This threat model is written against the dormant posture. That has three consequences for triage:
-
The (documented) "we will address security reports" commitment is what makes a threat model worth writing at all. It is the load-bearing claim under §4.13’s
VALIDrow. -
"Fixed in a release" is no longer a default disposition; many
VALIDoutcomes will be addressed by an advisory plus guidance to migrate, rather than a CVE+fix release. The model should not promise what the project will not deliver. -
Anything the model would have said about future evolution (
§4.12 Conditions that would change this model) collapses: the dominant condition is "Flume returns to ACTIVE status or new contributors take on a component."
|
Note
|
Open meta question for the PMC (§4.14, wave 1): whether the published threat model should explicitly recommend migration away from Flume in §4.10, or remain neutral and let the README banner carry that message. Both are coherent; the choice is editorial. |
Flume has no in-repo SECURITY.md, no in-repo threat-model document, and no security-scoped FAQ. (documented: find . -iname "security*" -o -iname "threat*" returns nothing under the repo root.) The closest existing artifacts are:
-
The README warning and the linked Logging Services dormant-projects announcement (documented).
-
The ASF-wide security policy at
https://www.apache.org/security/(documented), which is the reporting channel of record. -
The Flume User Guide’s per-component documentation, which states SSL/Kerberos options inline with each source/sink. The User Guide is a capability document, not a policy document — it says what can be configured, not what the project commits to.
-
The CHANGELOG / JIRA history, which records past CVE responses (FLUME-3395 for CVE-2021-44228, FLUME-3356, FLUME-3426, etc.) (documented).
Per §3.1a of the skill, the new threat model becomes the canonical security-policy artifact for the project and should be linked from the README banner alongside the dormant-status link. A short SECURITY.md pointing to this document and to apache.org/security/ would also be appropriate (open question §4.14).
Flume is not one component — it is a runtime (the agent process) plus an open-ended catalog of bundled sources, channels, sinks, interceptors, serializers, and selectors. Triage decisions hinge on which family a finding lands in. The model carves the surface as follows:
| Family | Representative entry point | Touches OS / network? | In model? | Notes |
|---|---|---|---|---|
Agent runtime (node, app, configuration provider) |
|
process boundary, filesystem, optional HTTP/ZK config fetch |
Yes |
The core daemon. Loads and reloads the topology configuration. |
Configuration providers |
|
filesystem, HTTP(S), ZooKeeper |
Yes |
|
Configuration filters |
|
env vars, external process, Hadoop credential store |
Yes |
Resolve indirected secrets at agent start. |
Core network sources (Avro, Thrift, HTTP, Syslog TCP/UDP, Netcat, MultiportSyslog) |
|
network listener |
Yes |
Primary attacker-reachable surface. SSL/TLS support is per-source and optional. |
Core OS sources (ExecSource, SpoolDirectorySource, StressSource, SequenceGenerator) |
|
filesystem, child processes |
Yes — but operator-trusted inputs only |
|
Bundled sources (modular): JMS, Scribe, Taildir |
|
filesystem, JMS broker, network |
Yes |
|
Bundled channels: Memory, File, Spillable-Memory, Kafka, JDBC |
|
filesystem, Kafka cluster, JDBC |
Yes |
File channel optionally provides AES/CTR encryption-at-rest. |
Bundled sinks (core): HDFS, HBase(2), Hive, ElasticSearch, Kafka, Avro, Thrift, RollingFile, Null, Logger |
|
network egress (mostly to authenticated downstreams) |
Yes |
Sinks generally talk to trusted, authenticated downstreams configured by the operator. |
Bundled sinks (modular): HTTP, IRC, Morphline-Solr |
|
network egress |
Yes |
|
Interceptors, selectors, serializers |
|
in-process only |
Yes |
Operate on event bodies / headers in memory. |
RPC client SDK ( |
|
network egress |
Yes — caller side |
Library used by applications and by |
Embedded agent ( |
|
in-process; channel I/O |
Yes |
Small library that runs an agent inside a host application. |
log4j 1.x appender |
|
network egress to Avro source |
Yes — caller side |
log4j 1.x is itself end-of-life; see §4.5. |
Monitoring endpoints: JMX, JSON HTTP, Prometheus HTTP, Ganglia |
|
network listener (HTTP) / UDP (Ganglia) |
Yes |
Unauthenticated by design (see §4.9). |
|
|
filesystem |
Yes |
Operator-only CLI; trusted-input surface. |
|
repo only, not shipped runtime |
n/a |
No (out of scope §4.3) |
Test scaffolding. |
Third-party / |
n/a |
n/a |
No — there are none |
Flume has no |
Use cases and threats Flume does not attempt to address. Findings in any of these categories are closed OUT-OF-MODEL per the row indicated.
-
Flume OG / 0.9.x. The 1.x line is a complete rewrite; nothing in this model applies to the pre-1.0 codebase. (documented: README.md)
-
Flume as a public-internet-facing service. Flume agents are intended to run inside a trusted network (e.g., one operator’s data-plane) and to be addressable only by other agents, by trusted producers, or by operators. Exposing an Avro, Thrift, HTTP, or Syslog source directly to the public internet is out of model. (inferred from documentation pattern and the absence of any default authentication on most sources)
-
Flume as a multi-tenant security boundary. Within a single agent there is no isolation between sources/sinks/channels: any sink can in principle read events from any channel the configuration wires it to; any interceptor sees every event flowing through. The agent is one trust domain. (inferred from architecture)
-
Operator-controlled inputs treated as adversarial.
ExecSourceruns an operator-specified command.SpoolDirectorySourcereads files from an operator-specified directory. The agent configuration file itself is operator-controlled. None of these are attacker-controlled in the threat model; a finding that requires an attacker to write to the spool directory, supply the exec command line, or alterflume.confisOUT-OF-MODEL: trusted-input. (inferred — wave-1 question for the PMC) -
log4j 1.x. The
Log4jAppenderlives in the repository for backward compatibility with applications that still emit log4j 1.x events; log4j 1.x itself reached EOL in 2015 (documented: Apache Logging Services 2015-08 announcement). CVEs in log4j 1.x are out of scope for this model; CVEs in the Flume appender code are in scope. -
Supply-chain hygiene of Flume’s runtime dependencies. Flume 1.11.0 / 1.12.0 pin dated versions of Jetty, Hadoop, Kafka client, Jackson, Avro, Thrift, Netty, and many others. The dormant project does not commit to keeping these patched (documented: dormant-status policy). A report that a transitive dependency has a CVE, without a demonstration that the CVE is reachable from Flume’s documented inputs, is
OUT-OF-MODEL. Reports that a CVE is reachable via a documented Flume input remainVALIDunder §4.13. -
Build, release, and SDLC hygiene of the project itself (action pinning, branch protection, reproducible builds, signing of release artifacts beyond ASF defaults). Out of scope per skill §1.
-
flume-ng-testsintegration test scaffolding, examples in user-guide snippets, sample configurations underconf/*.template. (inferred)
| Boundary | Inside (trusted) | Outside (in-scope adversary) |
|---|---|---|
Agent process boundary |
All in-process code: every source, channel, sink, interceptor, serializer, the configuration provider, and any plugin JAR on the configured classpath |
Other processes on the host; networks the agent is not configured to listen on |
Configuration file |
The |
Anyone who can modify the file is already trusted (and a finding requiring this is out of model per §4.3) |
Network source (Avro/Thrift/HTTP/Syslog/Netcat) |
The framed bytes after deserialization by the source handler, once committed to the channel |
The bytes-on-the-wire from clients, whether or not TLS is configured. If TLS is configured, after the TLS termination the bytes are still attacker-controlled at the application layer. |
File-system source (SpoolDirectory, Taildir) |
The file contents, the directory path, and the file names — all assumed operator-managed |
n/a — these are operator-trusted inputs per §4.3. |
Channel boundary |
Events committed to a channel transaction |
n/a — internal |
Sink → external system |
The sink writes to a downstream that the operator has authenticated against (HDFS Kerberos, Hive principal, Kafka SSL/SASL, etc.). The downstream is trusted by the operator’s choice, not by Flume. |
Network attacker between agent and downstream (defended by the downstream’s own transport, when the operator enables it). |
Monitoring HTTP endpoint |
The JSON metrics payload |
Anyone who can reach the monitoring port. This boundary is intentionally permissive per §4.9. |
Inter-agent RPC ( |
Bytes after the source has deserialized them |
The wire. Mutual TLS is optional and must be enabled at both ends. |
The §4.4 boundary table licenses these per-family tests. A triager applies the relevant one before assigning a §4.13 disposition.
-
Network sources (Avro, Thrift, HTTP, Syslog, Netcat, MultiportSyslog, Scribe). In-model only if reachable from an unauthenticated remote peer’s bytes via the configured handler’s parsing path.
-
JMS, Kafka, ZooKeeper. In-model only if reachable from broker/peer-supplied bytes; broker administration is operator-trusted.
-
Taildir, SpoolDirectory, Exec. In-model only if reachable from the operator-trusted input → channel pipeline without an attacker controlling the file path, command, or contents.
-
Configuration provider. In-model only if reachable from the bytes the agent fetches from the configured source (HTTP, ZooKeeper, or file). For the HTTP provider, in-model only when an attacker can serve those bytes; for the file/classpath provider, never in-model (operator-trusted).
-
Sinks. In-model only if reachable from an event the channel can deliver (i.e., from one of the in-model source paths above).
-
RPC SDK / Log4jAppender / embedded agent. In-model only if reachable from attacker-controlled event data fed through the API by the embedding application and the failure mode affects the embedding process, not just the host application logic.
-
Monitoring (HTTP/JMX/Prometheus/Ganglia). In-model only as a resource / availability surface; information disclosure of metrics is explicitly disclaimed in §4.9.
-
Java: Oracle/OpenJDK 8 build target (documented: README.md,
pom.xml). Newer JDKs may work for execution but are not first-class. The wave-3 question is whether the PMC supports running on JDK 11/17/21 for security purposes (open §4.14). -
OS: Linux is first-class; Windows is supported by the bundled
flume-env.ps1.templateandbin/scripts but is not the primary test target. (inferred) -
Threading: Sources, channels, and sinks run in distinct threads; the channel transaction API is thread-safe by contract. (inferred from API contract)
-
Filesystem: File-channel and Taildir source assume POSIX semantics (rename-is-atomic, mtime-monotone). On filesystems that do not provide these (NFS, some FUSE filesystems), reliability claims weaken. (inferred from prior FLUME bug history)
-
Clock: Several interceptors (TimestampInterceptor,
HostInterceptor) and sinks (HDFS bucket selection) depend on the system clock. A skewed clock degrades correctness but is not a security finding under the model. (inferred) -
Process privilege: The agent is expected to run as an unprivileged service account. Sources that bind privileged ports (Syslog 514) require the operator to grant capabilities; Flume itself does not. (inferred — wave-2 question)
A non-exhaustive negative-claim inventory (all (inferred); wave-2 questions):
-
The agent does not install signal handlers beyond JVM defaults.
-
The agent does not
fork()orexec()arbitrary child processes except via:-
ExecSource(operator-supplied command, by design) -
ExternalProcessConfigFilter(operator-supplied command, by design) -
Any sink that delegates to a Hadoop/Hive/HBase client that itself shells out (out of Flume’s control)
-
-
The agent does not modify process-wide JVM state beyond installing JMX MBeans and Jetty MBeans when monitoring is enabled.
-
The agent does not read environment variables except via
EnvVarResolverProperties(when explicitly enabled) andEnvironmentVariableConfigFilter(when configured). (open question whether the agent reads any env var unconditionally at startup) -
The agent does not write outside the directories named in its configuration (file-channel data/checkpoint dirs, HDFS local cache if any, log4j2 log directory). (open question)
Flume is shipped as a single binary distribution; there are no compile-time -D defines that change security behavior. Security-relevant variation is runtime configuration:
| Knob | Default | Less-secure default? | Maintainer stance (PMC ruling needed) | Section impact |
|---|---|---|---|---|
Network sources |
|
Yes |
(open §4.14 wave 1) — likely "operator must enable for production" |
§4.10 |
HTTP/HTTPS configuration provider |
|
Yes |
(open §4.14 wave 1) |
§4.10 |
HTTP metrics server ( |
no TLS, no auth available at all |
N/A — by design |
|
§4.9, §4.11a |
File channel |
no encryption-at-rest |
Possibly |
(open §4.14) — likely "operator’s choice; encryption is for media-loss threats, not in-host adversaries" |
§4.9 |
ZooKeeper config provider ACLs |
inherits from cluster |
? |
(open §4.14) |
§4.10 |
Kerberos for HDFS / HBase / Hive / Kafka sinks |
disabled if not configured |
Yes in most production deployments |
(open §4.14) — likely "operator’s choice; Flume does not impose" |
§4.10 |
|
not the default |
n/a (the non-lax verifier is default) |
(inferred — needs confirmation) Is |
§4.9 |
|
not enabled |
n/a |
Operator-only by definition; in-model only that the invocation mechanics are safe given an operator-trusted command. |
§4.6 |
log4j2 logging configuration (Flume’s own logs) |
|
n/a |
Plugin lookups are restricted post-FLUME-3433 (documented); lookup-related findings against Flume’s own logs are |
§4.11a |
-
Network bytes on configured listener ports (one source per port). Format varies by source: Avro IPC, Thrift, HTTP request body, syslog line, netcat newline-terminated, scribe.
-
Filesystem inputs: files in the Spool directory, files tailed by Taildir, the agent configuration file, file-channel data and checkpoint files, optional encryption keystores.
-
Broker inputs: JMS messages, Kafka records (for Kafka channel and Kafka source), ZooKeeper znodes (for ZK configuration provider).
-
Process inputs: stdout/stderr of the command run by
ExecSource, stdout of the command run byExternalProcessConfigFilter. -
In-process API inputs:
EmbeddedAgent.put(…)and the RPC SDK’sRpcClient.append(…)from the embedding application.
The table is grouped by component family; one row per attacker-relevant entry point. Caller means "the entity that supplies these bytes." A yes in the third column means the model treats those bytes as attacker-controlled; a no means they are operator/peer-trusted and a finding requiring control of them is out of model.
| Entry point | Parameter | Attacker-controllable? | Caller must enforce | Notes |
|---|---|---|---|---|
|
Avro IPC frame body, headers |
Yes |
TLS termination at source (optional); rate limiting at LB; downstream allow-list |
Generic Java deserialization is not used by AvroSource (Avro has its own schema-driven wire format), but caller-supplied schema lookups should be reviewed. |
|
TLS client cert (when mTLS configured) |
Yes (the cert presented) |
Trust store curation |
Without mTLS, no peer authentication. |
|
Thrift TBinaryProtocol message |
Yes |
Same as Avro |
|
|
HTTP request body, headers, method, path |
Yes |
Handler-specific input bounds; Jetty version pinning |
Default handler is JSON; pluggable. |
|
|
Yes |
Do not trust headers for source-IP attribution without an upstream that strips them |
Common false-friend; cross-reference §4.9. |
|
syslog line bytes |
Yes |
Bound |
|
|
UDP packet |
Yes |
Same as TCP; spoofable source IP is inherent |
|
|
line bytes |
Yes |
Documented as a testing source; not for production. (open §4.14 — confirm) |
|
|
stdout of the command |
No (operator-trusted) |
The command line itself is trusted; the command’s output is trusted via that command |
If the command shells out to a tool that reads attacker-controlled files, the operator has extended trust deliberately. |
|
File contents in the spool dir, file names |
No (operator-trusted) |
Path sanitization is operator’s job |
|
|
File contents being tailed, file names |
No (operator-trusted) |
Same as Spool |
|
|
JMS message body, properties |
Peer-authenticated |
Broker ACLs and broker TLS are the operator’s domain |
|
|
Thrift Scribe message |
Yes |
Same as Thrift; protocol largely historical |
|
|
Kafka record bytes |
Peer-authenticated (if SASL/SSL configured) |
Kafka cluster ACLs are operator’s domain |
|
HTTP |
HTTP response body containing properties |
Yes if the URL is reachable to an attacker; otherwise no |
TLS, host-pinning, and authentication on the config endpoint |
The most sensitive deserialization surface in the runtime — a poisoned config can pivot to anything Flume can do. Default auth is |
ZooKeeper |
znode contents |
Cluster-authenticated |
ZK ACLs |
|
|
env var name as configured |
No (operator-trusted) |
Env vars are trusted because the operator chose which to read |
|
|
stdout of |
No (operator-trusted) |
The command itself is trusted; shell metacharacter handling in the key is the question — see §4.11 |
|
|
event body, headers |
Caller-controlled |
The caller application is responsible for not feeding adversary-controlled headers that downstream sinks would interpret unsafely (e.g., HDFS path headers — see §4.11) |
|
|
log4j 1.x |
Caller-controlled |
log4j 1.x EOL caveat applies |
|
HTTP metrics endpoint |
URL, method |
Yes (whoever can reach the port) |
Operator must firewall the port |
Returns metrics; no auth, no TLS option. By design — §4.9. |
-
Each source has its own batch size and per-event size cap (
maxLineLength,eventSize, etc.) configurable per source. The defaults are generous and intended for legitimate logging volumes; the model does not promise survival under an adversary that sustains the maximum rate. (inferred — see §4.9 resource property) -
Channels have a
capacityandtransactionCapacity. Exceeding them producesChannelException, not crash — that is a model property (§4.8). -
The bounded-vs-unbounded line on memory/CPU under adversarial input is a wave-1 question for the PMC — see §4.9 and §4.14.
Flume is a network service; the role split per skill §4.2 applies.
| Actor | Capability and assumed intent (in scope unless noted) |
|---|---|
Operator / deployer |
Trusted. Writes the agent configuration, chooses which sources/sinks to enable, manages keystores and downstream credentials. Out of scope as an adversary — an operator who is hostile to their own deployment has won. |
Upstream event producer (the application emitting events into an Avro/Thrift/HTTP/Syslog source) |
Untrusted by default if the source is exposed to anything beyond a curated set of producer hosts. May send malformed framing, oversized events, adversarial event bodies, header injection. May spoof source-IP for UDP sources. Cannot read events sent by other producers (Flume does not echo). |
Peer Flume agent (the AvroSink/ThriftSink at the other end of an RPC link) |
Authenticated-but-untrusted in tiered deployments with mTLS. Without mTLS, no stronger than any other upstream producer. Note: Flume is not a Byzantine-consensus system — there is no honest-fraction threshold; each agent independently makes routing decisions. |
Downstream broker / store (HDFS NameNode, Kafka broker, Hive metastore, etc.) |
Trusted via operator-configured credentials. A compromised downstream can in principle return malicious responses that the sink’s client library handles; that is the downstream’s CVE, not Flume’s, unless Flume’s adapter mishandles a response (in which case it is in scope). |
Network attacker between agent and downstream |
In scope only as far as TLS / SASL / Kerberos on the relevant link addresses them. Flume does not provide network-attacker defenses itself; it relies on configuration of the underlying library. |
Co-tenant on the host |
Out of scope. A process on the same host as the Flume agent already has equivalent or greater capability than reaching the Flume API surface. |
Attacker with write access to |
Out of scope per §4.3. Equivalent to compromise of the operator. |
Attacker with read access to |
Out of scope — file-system ACLs are the operator’s domain, and the configuration contains secrets the operator chose to put there. |
Side-channel adversary (timing, memory, cache) |
Out of scope. Flume does not provide any constant-time or otherwise side-channel-resistant primitive. (see §4.9) |
Internet-scale adversary scanning for exposed agent ports |
Out of scope as a Flume responsibility. The dormant-status policy explicitly does not commit to a hardening posture sufficient to make exposed agents safe. The model documents the assumption (§4.3) that agents are not internet-facing. |
Each property states: (P) the property, © the condition(s) under which it holds, (S) the violation symptom, (T) the severity tier (security-critical warrants a CVE / coordinated disclosure; correctness-only is an ordinary bug), and (prov) the provenance tag.
| Property | Condition | Violation symptom | Tier | Prov |
|---|---|---|---|---|
Memory safety of the agent JVM on malformed network input |
All in-model sources; default JDK; latest Flume release |
JVM crash (SIGSEGV); OOM via uncontrolled allocation directly traceable to a single small input |
security-critical |
(inferred — wave 1) |
At-least-once delivery for events committed to a transactional channel (File channel; Kafka channel) |
Configured durable channel; sink that completes a |
Event silently dropped after |
correctness-only (operational); occasionally security-critical if used to defeat audit logging |
(documented: User Guide; (inferred) for the security-critical sub-case) |
No remote code execution from untrusted source bytes |
All in-model network sources, with their documented handlers (i.e., not a user-supplied handler that itself deserializes Java objects) |
Arbitrary code execution in the agent |
security-critical |
(inferred — wave 1) |
Bounded per-event memory given documented per-source caps |
Operator has configured the cap; source obeys it |
Single-event memory consumption exceeds the configured cap by more than a constant factor |
security-critical (DoS) |
(inferred — wave 1 and threshold question) |
|
Polling configuration providers; the documented reload semantics |
Mid-flight events lost or duplicated beyond at-least-once tolerance |
correctness-only |
(inferred — needs maintainer confirmation that this is even a claimed property) |
TLS for in-model network sources when |
Operator has configured a valid keystore; uses a non-deprecated TLS version (Flume exposes protocol and cipher allow-lists per FLUME-3275/3276) |
Connection accepted on plaintext when ssl=true; weak protocol negotiation despite allow-list |
security-critical |
(documented: CHANGELOG FLUME-3275/3276; (inferred) for the negative claim) |
Kerberos authentication on HDFS / HBase / Hive sinks when configured |
|
Sink writes as the wrong principal, or anonymously |
security-critical |
(documented: User Guide; (inferred) for failure semantics) |
Hostname verification on outbound TLS (sinks, HTTP config provider) |
|
Sink accepts a server cert for the wrong host |
security-critical |
(documented: FLUME-3315; FLUME-3437 for providerUrl validation) |
File-channel encryption-at-rest provides confidentiality of channel data against an attacker who later reads the media |
|
Channel data recoverable from raw files |
security-critical (in deployments that opted in) |
(documented: encryption package) |
The agent does not deserialize untrusted Java |
All in-model sources with their documented handlers |
Demonstration that any in-model code path reaches |
security-critical |
(inferred — wave 1; if the PMC ratifies, this is the headline §4.8 property) |
|
Note
|
Threshold for resource properties
The skill explicitly requires the PMC to draw a categorical line on resource consumption. Until the PMC rules in §4.14, this model takes the position: "super-linear CPU or memory growth in a single event’s size beyond the documented cap is a bug; sustained high request rates from many connections are not." That is the proposed answer for the maintainer to confirm, correct, or replace. |
-
No authentication on the JSON/Prometheus HTTP metrics endpoint. The endpoint is by design unauthenticated and unencrypted. (documented:
HTTPMetricsServersource has no auth or TLS code paths.) Operators must firewall the port. -
No authorization model for sources. Any client that can connect to a source’s port (subject to optional TLS / mTLS) can submit events. Flume does not provide a per-tenant identity, a per-source ACL, or rate limiting.
-
No data-content authentication. Event bodies and headers are not authenticated end-to-end. A producer that has compromised an intermediate agent can inject events; the model does not provide a MAC over events.
-
No defense against decompression bombs or other amplification within event bodies if a sink/serializer decompresses (e.g., Snappy, Gzip via Hadoop libraries in the HDFS sink path). (inferred — wave 2)
-
No constant-time primitives. Flume does not use cryptographic comparisons in any documented authentication path; if it did, side-channel adversaries are still out of model per §4.7.
-
No defense against an attacker who controls headers used by sinks to choose output paths. HDFS
path = /data/%{client}/logwill route based on attacker-suppliedclientheader; that is a §4.11 misuse, not a Flume property.
These features are commonly mistaken for security properties they do not satisfy:
-
"Reliable delivery" — this is a reliability property (no data loss on agent restart or channel failure), not an integrity property (no data tampering on the wire). Reliable delivery does not authenticate the sender.
-
The TLS option on a source — this protects the bytes-on-the-wire between the configured peer and the source. It does not authenticate the producer application upstream of that peer, and unless mTLS is enabled with a curated trust store, it does not authenticate the peer at all.
-
Kerberos on HDFS/Hive/HBase sinks — authenticates the agent to the downstream. It says nothing about the event producer’s identity.
-
File-channel encryption — protects against recovery from disk media later. It does not protect against any in-host adversary, because the key is in memory and the data passes through plaintext channels (interceptors, serializers) before being written.
-
The agent configuration file — is not a sandbox. Loading a plugin from the classpath is full code-execution-as-the-agent. There is no signing or verification of plugin JARs.
-
Log injection / forging downstream log lines. If event bodies are written to a log-aggregation store that interprets newlines or markers (e.g., a tail-following tool), an attacker who controls event content can inject lines. Operators using Flume as part of an audit pipeline must apply integrity controls at the audit layer.
-
Header injection into headers that sinks treat as routing data. As above; the canonical case is HDFS path placeholders. (§4.11)
-
Replay attacks. Re-sending captured Avro/Thrift frames will deliver duplicate events. The downstream is responsible for idempotency or de-duplication.
-
Source-IP spoofing for UDP-based sources (
SyslogUDPSource,NetcatUdpSource). Inherent to UDP; cannot be addressed at this layer. -
Resource exhaustion via many slow connections against TCP sources. Mitigations belong at the network / LB layer.
-
Adversary-influenced timing of Kerberos ticket renewal or TLS handshake leading to outage. Out of model per §4.7 (side-channel) and §4.9 (no liveness guarantees under load).
A short, action-oriented list of what an operator of a Flume agent must do for §4.5–§4.7 to hold. This is a contract, not a how-to.
-
Do not expose any source’s listening port to the public internet, or to any network that includes untrusted producers, unless mTLS is configured and the trust store is curated.
-
Enable TLS (
ssl = true) on every network source that listens outsidelocalhost. -
Firewall the monitoring port. It returns operational metadata with no authentication.
-
If using the HTTP configuration provider, set HTTPS and basic-auth credentials. The configuration the agent fetches is fully privileged.
-
Run the agent as an unprivileged service account. Do not run as root, even when binding to syslog port 514; use OS capabilities or a port-forwarder.
-
Treat
flume.confas a secrets-bearing file (mode 0600, owned by the service account). Use config-filters (environment-variable,external-process, or Hadoop credential store) to keep raw secrets out of the file. -
Validate operator-supplied inputs at the operator boundary.
ExecSourcecommands, Spool directory contents, and Taildir glob patterns are operator-trusted by the model — if the operator’s processes accept those inputs from elsewhere, the operator must enforce sanitization upstream. -
Pin and review dependency versions when building from source. The dormant project does not commit to keeping transitive dependencies patched.
-
Do not use Flume for audit logging without an independent integrity control on the audit pipeline (downstream signing, append-only storage with hash chaining).
-
Do not place the agent inside an application that treats events as security-sensitive without independent authentication.
-
Plan migration. Per the dormant-status policy, new releases are unlikely. Operators should treat the current Flume version as the last version they will receive, and plan replacement on a timescale that suits the threats their deployment is exposed to.
-
Passing attacker-influenced event headers into HDFS / file-roll
pathtemplates. Headers like%{client}or%{tenant}are expanded by sinks; if the attacker controls them, they choose the output path. Mitigation: whitelist allowed header values via an interceptor; use only operator-set headers in path templates. -
Using
NetcatSourcefor production traffic. Documented as for testing; no protocol framing, no flow control. Mitigation: use Avro or Syslog instead. -
Using
ExecSourcewithtail -Fon user-writable files. The source then trusts the contents of an operator-claimed-trusted file that is actually attacker-writable. Mitigation:Taildirplus filesystem ACLs. -
Wiring
MemoryChannelbetween sources and sinks that the operator considers "reliable." Memory channel loses events on JVM crash by design. Mitigation: File channel for any reliability requirement. -
Running multiple agents on the same host with overlapping channel directories. File channel is single-writer; concurrent access corrupts state.
-
Putting cleartext credentials in
flume.conf. The file is operator-trusted but routinely shipped via configuration management tools that may not protect it as a secret. -
Treating the gzip-magic file-extension on rolled HDFS files as integrity. The HDFS sink can write gzipped output; the compression footer is not a MAC.
-
Enabling the HTTP configuration provider without TLS or auth. The provider will then re-load any properties any attacker can serve to it.
-
Replaying a captured Avro frame. If the downstream is not idempotent and Flume is in the audit path, the attacker has now duplicated an event into the audit record.
-
Loading a plugin JAR from a writable directory. The agent classpath is operator-trusted; if the operator allows write access, anyone with that access has code-execution-as-the-agent.
This section is the highest-leverage artifact for triage. Entries are findings that tools or researchers raise repeatedly that are not bugs under the model.
-
"`HTTPMetricsServer` has no authentication" → §4.9 / §4.10. By design; operator-firewalled. Disposition:
BY-DESIGN: property-disclaimed. -
"`ExecSource` allows arbitrary command execution" → §4.6 / §4.3. The command is operator-supplied; reaching it requires write access to
flume.conf. Disposition:OUT-OF-MODEL: trusted-input. -
"`ExternalProcessConfigFilter` enables command injection" → §4.6. Same as above; the command is operator-supplied and the key is operator-supplied (via the configuration). The implementation uses
Runtime.exec(commandParts)with the key as a separateargvelement, not shell-interpreted. Disposition:OUT-OF-MODEL: trusted-input. -
"Default
ssl = falseonAvroSourcepermits MITM" → §4.10. Operator must enable. Disposition:OUT-OF-MODEL: non-default-build(with the §4.5a maintainer ruling pending). -
"`MemoryChannel` loses data on crash" → §4.9. By design; channel choice is the operator’s. Disposition:
BY-DESIGN: property-disclaimed. -
"Source-IP header is trusted" → §4.6. Documented false-friend; producer-supplied headers are attacker-controllable. Disposition:
OUT-OF-MODEL: trusted-input(the field is in the trust-untrusted list). -
"CVE in transitive
<dep>reachable in theory" → §4.3. In-model only with a demonstration of reachability via a documented Flume input. A static-analysis hit on a dependency, on its own, isOUT-OF-MODEL: unsupported-componentfor the dependency. -
"Log4j 1.x appender vulnerable to CVE-X in log4j 1" → §4.3. log4j 1.x is EOL; only bugs in Flume’s appender code are in scope.
-
"`LaxHostnameVerifier` exists in the codebase" → §4.5a. It is not the default; only deployments that opt in are affected, and those report under
OUT-OF-MODEL: non-default-build. -
"`SyslogUDPSource` accepts spoofed source IPs" → §4.9. Inherent to UDP. Disposition:
BY-DESIGN: property-disclaimed.
(Expand on each iteration with whatever the next round of scanners or researchers reports.)
-
Flume returns to ACTIVE status in Logging Services. Many of the "we will not patch dependencies" assumptions soften.
-
A new source, sink, or channel is added in core. New row in the §4.2 table; new rows in the §4.6 trust table.
-
The default for any §4.5a knob flips (e.g.,
sslbecomes default-on). -
A configuration mechanism gains a remote, network-fetched mode without authentication by default (already the case for HTTP config provider — handled).
-
A vulnerability report cannot be cleanly assigned to one of the §4.13 dispositions. That is evidence of a
MODEL-GAPand the model must be revised before the report is closed. -
A bundled third-party dependency adds a new wire format that Flume now serves (e.g., a new sink accepts inbound traffic of a new shape).
| Disposition | Meaning for Flume | Licensed by |
|---|---|---|
|
Violates a §4.8 property via an in-scope adversary and input. Reported per |
§4.8, §4.6, §4.7 |
|
No §4.8 property is violated, but a §4.11 misuse is easy enough to warrant a fix at maintainer discretion. Reported privately. Typically no CVE. |
§4.11 |
|
Requires attacker control of a parameter the §4.6 table marks trusted. Closed with a citation to the row. |
§4.6, §4.3 |
|
Requires a capability §4.7 excludes (co-tenant, write-access to |
§4.7 |
|
Lands in |
§4.3 |
|
Only manifests with a knob the PMC has designated dev-only or operator-must-flip (per §4.5a). |
§4.5a |
|
Concerns a property §4.9 explicitly does not provide (unauthenticated metrics, no constant-time, no MAC, etc.). |
§4.9 |
|
Matches a documented entry in §4.11a. |
§4.11a |
|
Cannot be routed to any of the above. Triggers a §4.12 revision before the report is closed. |
§4.12 |
Grouped into waves of 3–7 per skill §3.2. Each question states a proposed answer for the PMC to confirm, correct, or strike.
-
Proposed: "An exposed Avro/Thrift/HTTP/Syslog source on the public internet is out of model — Flume was designed for trusted-network deployments." → §4.3, §4.10. Confirm?
-
Proposed: "An attacker with write access to
flume.confis out of model — equivalent to operator compromise." → §4.3, §4.7. Confirm? -
Proposed: "The headline §4.8 property is: No documented Flume source on its default handler invokes Java
ObjectInputStream.readObject()on attacker-controlled bytes. A counterexample isVALIDand security-critical." → §4.8. Confirm; if so, is there any source/handler combination this does not cover? -
Proposed: "Resource-consumption threshold: super-linear CPU or memory growth in a single event beyond the documented per-event cap is a bug; sustained high connection rates are not." → §4.8 resource row, §4.9. Confirm threshold or supply a different one.
-
Proposed: "Defaults that are less-secure (
ssl = false, HTTP config providerauth = none, no Kerberos on HDFS sink) are operator-must-enable, not supported production posture — therefore findings against pure defaults areOUT-OF-MODEL: non-default-build." → §4.5a, §4.10, §4.13. Confirm? If the PMC disagrees on any of these, they becomeVALID. -
Proposed: "The dormant-status policy stands: security reports are triaged and answered, but the typical response is an advisory and migration guidance, not a fix release. The threat model documents this honestly rather than implying a fix pipeline." → §4.1. Confirm?
-
Proposed: "Flume does not install signal handlers beyond JVM defaults; does not
fork()/exec()except viaExecSource/ExternalProcessConfigFilter/ downstream client libraries; does not read env vars except via the documented filters." → §4.5. Are any of these wrong? Any unconditional env-var read at startup we should add to the list? -
Proposed: "Flume targets Java 8 for build and execution; running on JDK 11/17/21 is best-effort and security claims weaken if a JDK-specific issue is involved." → §4.5. Confirm or extend.
-
Proposed: "Flume on Windows is supported but not first-class for security purposes; the wave-1 threat model applies to Linux deployments." → §4.5. Confirm?
-
Proposed: "`NetcatSource` is testing-only; a finding that requires a NetcatSource in production is
OUT-OF-MODEL: unsupported-componentorVALID-HARDENINGat best." → §4.11. Confirm — or is Netcat considered a real production option somewhere? -
Proposed: "POSIX rename/atomicity is assumed by File channel and Taildir; non-POSIX filesystems are best-effort." → §4.5. Confirm?
-
Proposed: "Sinks delegate authentication and transport security to their downstream’s client library (HDFS/Kerberos, Kafka/SASL, Hive/Kerberos, HBase/Kerberos). A Flume-specific failure mode is in scope only when Flume’s adapter code mishandles a response or credential lifecycle (e.g., FLUME-3049 type)." → §4.4. Confirm?
-
Proposed: "Default JSON handler on
HTTPSourcedoes not invoke Java native deserialization; pluggable handlers may, and a user-supplied handler is the user’s problem." → §4.8. Confirm? Is the JSON handler the only one in core that’s explicitly safe? -
Proposed: "Compression handling in HDFS sink (Snappy/Gzip via Hadoop libs) does not include decompression-bomb defenses at the Flume layer; that is
BY-DESIGN: property-disclaimed." → §4.9. Confirm or reject? -
Proposed: "`LaxHostnameVerifier` is opt-in only and never wired by default; any code path that selects it implicitly is itself a bug." → §4.5a. Verify against current code.
-
Proposed: "Header injection into HDFS path templates is a §4.11 misuse, not a §4.8 violation — the responsibility is on the operator to use only operator-set headers in path templates." → §4.11. Confirm; should we add an interceptor recommendation or stay descriptive?
-
Where does this document live? Proposed:
docs/threat-model.adocin the repo, linked from the README banner above the dormant notice. Confirm or pick alternative. -
Does a thin
SECURITY.mdget added that points to (a) this file and (b)apache.org/security/? Proposed: yes. Confirm. -
Versioning binding — proposed: "the model is tagged against
mainat the date in the header; a report against an older release is triaged using the model in effect at that release, but practically the dormant-state model is what will be used." Confirm or refine. -
Sign-off process — proposed: a LAZY-CONSENSUS vote on
dev@logging.apache.orgonce the wave-1/2/3 answers are folded in. Confirm.
A threat-model.yaml sidecar will be derived from this document once the PMC ratifies wave 1, so triage tooling (and AI-assisted triage) can consume the §4.2 component-family table, the §4.6 trust table, the §4.8 properties, the §4.9 disclaimers, and the §4.11a known-non-findings without prose parsing. Deferred until the model is stable. (open §4.14)
-
✓ Every section is substantive or marked N/A with reason. (N/A used where Flume has no
contrib/.) -
✓ No bullet would be at home in a code review.
-
✓ No bullet restates README prose.
-
✓ Every non-trivial claim carries a
(documented)/(maintainer)/(inferred)tag (or is in a clearly-marked "Proposed" question). -
✓ Header reports a draft-confidence count.
-
✓ Every
(inferred)tag has a matching open question in §4.14. -
✓ Component families are modeled separately (§4.2 table).
-
✓ Build / configuration variants are enumerated (§4.5a).
-
✓ §4.9 and §4.10 are at least as substantive as §4.8.
-
✓ §4.9 names false-friend properties and well-known attack classes.
-
✓ §4.6 is a table, not prose.
-
✓ Every §4.8 property carries violation symptom and severity tier; the resource property states a threshold (proposed, pending PMC ruling).
-
✓ §4.11a is populated.
-
✓ §4.13 enumerates dispositions with section citations.
-
❏ Pending: a reader who has never seen Flume can answer "what threats has Flume taken responsibility for, and which have been left to me?" — gated on PMC wave-1 answers.
-
❏ Pending: a triager can route any finding to exactly one §4.13 row citing a section, without consulting the PMC — gated on PMC wave-1 answers.
-
✓ The document fits in one sitting (eight pages or so). Acceptable.