Skip to content

Instantly share code, notes, and snippets.

@ppkarwasz
Created May 13, 2026 14:44
Show Gist options
  • Select an option

  • Save ppkarwasz/485782a1a04a1940c47f4fa017d1767f to your computer and use it in GitHub Desktop.

Select an option

Save ppkarwasz/485782a1a04a1940c47f4fa017d1767f to your computer and use it in GitHub Desktop.
Flume threat model

Apache Flume Threat Model

Project

Apache Flume (https://github.com/apache/logging-flume)

Version/commit

main @ ff739dbe (2024-10-10, "Announce dormant status"); latest release 1.11.0

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

(documented) = stated in project / ASF artifacts (cite source); (maintainer) = stated by a Flume PMC member in response to this process; (inferred) = reasoned from code or absence — every such tag has a matching open question in §4.14.

Draft confidence

~24 documented / 0 maintainer / ~35 inferred (counts approximate; update on each revision)

About Flume
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

1.1. Project status (dormant)

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:

  1. 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 VALID row.

  2. "Fixed in a release" is no longer a default disposition; many VALID outcomes 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.

  3. 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.

2. Coexistence with existing security documentation

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).

3. Component-family table (§4.2)

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)

flume-ng-node:Application

process boundary, filesystem, optional HTTP/ZK config fetch

Yes

The core daemon. Loads and reloads the topology configuration.

Configuration providers

Properties, URI-based, HTTP(S), ZooKeeper

filesystem, HTTP(S), ZooKeeper

Yes

HttpConfigurationSource introduced in 1.10 (FLUME-3335) supports HTTP(S) with optional basic-auth.

Configuration filters

flume-ng-configfilters/*

env vars, external process, Hadoop credential store

Yes

Resolve indirected secrets at agent start. external-process shells out.

Core network sources (Avro, Thrift, HTTP, Syslog TCP/UDP, Netcat, MultiportSyslog)

flume-ng-core/source/*

network listener

Yes

Primary attacker-reachable surface. SSL/TLS support is per-source and optional.

Core OS sources (ExecSource, SpoolDirectorySource, StressSource, SequenceGenerator)

flume-ng-core/source/*

filesystem, child processes

Yes — but operator-trusted inputs only

ExecSource and SpoolDirectorySource deliberately consume operator-controlled inputs.

Bundled sources (modular): JMS, Scribe, Taildir

flume-ng-sources/*

filesystem, JMS broker, network

Yes

Bundled channels: Memory, File, Spillable-Memory, Kafka, JDBC

flume-ng-core/channel/, flume-ng-channels/

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

flume-ng-core/sink/, flume-ng-sinks/ and split modules

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

flume-ng-sinks/*

network egress

Yes

Interceptors, selectors, serializers

flume-ng-core/interceptor/, serialization/

in-process only

Yes

Operate on event bodies / headers in memory.

RPC client SDK (flume-ng-sdk)

org.apache.flume.api.*RpcClient

network egress

Yes — caller side

Library used by applications and by AvroSink/ThriftSink to talk to Flume agents.

Embedded agent (flume-ng-embedded-agent)

EmbeddedAgent

in-process; channel I/O

Yes

Small library that runs an agent inside a host application.

log4j 1.x appender

flume-ng-clients (Log4jAppender, LoadBalancingLog4jAppender)

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

instrumentation/*

network listener (HTTP) / UDP (Ganglia)

Yes

Unauthenticated by design (see §4.9).

flume-tools (CLI utilities)

flume-tools/*

filesystem

Yes

Operator-only CLI; trusted-input surface.

flume-ng-tests (integration tests)

repo only, not shipped runtime

n/a

No (out of scope §4.3)

Test scaffolding.

Third-party / vendor / contrib directories

n/a

n/a

No — there are none

Flume has no contrib/ or vendored third-party source tree in the runtime distribution. (inferred from ls -la)

4. Out of scope (§4.3)

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.

  1. 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)

  2. 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)

  3. 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)

  4. Operator-controlled inputs treated as adversarial. ExecSource runs an operator-specified command. SpoolDirectorySource reads 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 alter flume.conf is OUT-OF-MODEL: trusted-input. (inferred — wave-1 question for the PMC)

  5. log4j 1.x. The Log4jAppender lives 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.

  6. 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 remain VALID under §4.13.

  7. 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.

  8. flume-ng-tests integration test scaffolding, examples in user-guide snippets, sample configurations under conf/*.template. (inferred)

5. Trust boundaries and data flow (§4.4)

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 .properties agent configuration as written to disk by the operator, including secrets resolved via config-filters at startup

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 (AvroSink / ThriftSinkAvroSource / ThriftSource)

Bytes after the source has deserialized them

The wire. Mutual TLS is optional and must be enabled at both ends.

5.1. Reachability preconditions per family

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.

6. Environmental assumptions (§4.5)

  • 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.template and bin/ 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)

6.1. What Flume does not do to its host

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() or exec() 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) and EnvironmentVariableConfigFilter (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)

7. Build-time and configuration variants (§4.5a)

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 ssl = false

false (documented: User Guide)

Yes

(open §4.14 wave 1) — likely "operator must enable for production"

§4.10

HTTP/HTTPS configuration provider auth = none

none

Yes

(open §4.14 wave 1)

§4.10

HTTP metrics server (type = http)

no TLS, no auth available at all

N/A — by design

OUT-OF-MODEL: by design per §4.9

§4.9, §4.11a

File channel encryption = none

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

LaxHostnameVerifier (in flume-ng-node/net)

not the default

n/a (the non-lax verifier is default)

(inferred — needs confirmation) Is LaxHostnameVerifier ever wired in by default? If not, document it as opt-in.

§4.9

ExternalProcessConfigFilter

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)

conf/log4j2.xml

n/a

Plugin lookups are restricted post-FLUME-3433 (documented); lookup-related findings against Flume’s own logs are KNOWN-NON-FINDING if the default config is in use.

§4.11a

8. Inputs and trust (§4.6)

8.1. Inputs Flume accepts

  1. 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.

  2. Filesystem inputs: files in the Spool directory, files tailed by Taildir, the agent configuration file, file-channel data and checkpoint files, optional encryption keystores.

  3. Broker inputs: JMS messages, Kafka records (for Kafka channel and Kafka source), ZooKeeper znodes (for ZK configuration provider).

  4. Process inputs: stdout/stderr of the command run by ExecSource, stdout of the command run by ExternalProcessConfigFilter.

  5. In-process API inputs: EmbeddedAgent.put(…​) and the RPC SDK’s RpcClient.append(…​) from the embedding application.

8.2. Per-input trust table

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

AvroSource (network)

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.

AvroSource

TLS client cert (when mTLS configured)

Yes (the cert presented)

Trust store curation

Without mTLS, no peer authentication.

ThriftSource (network)

Thrift TBinaryProtocol message

Yes

Same as Avro

HTTPSource (network)

HTTP request body, headers, method, path

Yes

Handler-specific input bounds; Jetty version pinning

Default handler is JSON; pluggable.

HTTPSource

X-Forwarded-* / IP-in-header

Yes

Do not trust headers for source-IP attribution without an upstream that strips them

Common false-friend; cross-reference §4.9.

SyslogTcpSource / MultiportSyslogTCPSource

syslog line bytes

Yes

Bound eventSize; deprecated single-port variant should not be used (MultiportSyslogTCPSource preferred per @Deprecated on the class)

SyslogUDPSource

UDP packet

Yes

Same as TCP; spoofable source IP is inherent

NetcatSource / NetcatUdpSource

line bytes

Yes

Documented as a testing source; not for production. (open §4.14 — confirm)

ExecSource

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.

SpoolDirectorySource

File contents in the spool dir, file names

No (operator-trusted)

Path sanitization is operator’s job

TaildirSource

File contents being tailed, file names

No (operator-trusted)

Same as Spool

JMSSource

JMS message body, properties

Peer-authenticated

Broker ACLs and broker TLS are the operator’s domain

providerUrl was validated in FLUME-3437 (documented: CHANGELOG) — that fix is in-scope and a regression would be VALID.

ScribeSource

Thrift Scribe message

Yes

Same as Thrift; protocol largely historical

KafkaSource / KafkaChannel

Kafka record bytes

Peer-authenticated (if SASL/SSL configured)

Kafka cluster ACLs are operator’s domain

HTTP ConfigurationSource (FLUME-3335)

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 none.

ZooKeeper ConfigurationSource

znode contents

Cluster-authenticated

ZK ACLs

EnvironmentVariableConfigFilter

env var name as configured

No (operator-trusted)

Env vars are trusted because the operator chose which to read

ExternalProcessConfigFilter

stdout of command + key

No (operator-trusted)

The command itself is trusted; shell metacharacter handling in the key is the question — see §4.11

Runtime.exec(commandParts) with the key as a separate argv element; not shell-interpreted, but the key value originates from the agent configuration (operator-trusted by §4.3).

RpcClient.append(…​) (flume-ng-sdk)

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)

Log4jAppender (flume-ng-clients)

log4j 1.x LoggingEvent fields

Caller-controlled

log4j 1.x EOL caveat applies

HTTP metrics endpoint GET /

URL, method

Yes (whoever can reach the port)

Operator must firewall the port

Returns metrics; no auth, no TLS option. By design — §4.9.

8.3. Size and rate assumptions

  • 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 capacity and transactionCapacity. Exceeding them produces ChannelException, 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.

9. Adversary model (§4.7)

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 flume.conf

Out of scope per §4.3. Equivalent to compromise of the operator.

Attacker with read access to flume.conf

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.

10. Security properties Flume provides (§4.8)

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 Transaction.commit(); no operator-induced data loss (disk wipe, ZK loss)

Event silently dropped after commit()

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)

Application reloads configuration without restarting in-flight transactions inconsistently

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 ssl = true

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

flume-ng-auth module wired; valid keytab; UGI lifecycle preserved

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)

LaxHostnameVerifier not explicitly selected; default JSSE behavior

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

encryption.activeKey set; keystore protected; AES/CTR/NoPadding provider

Channel data recoverable from raw files

security-critical (in deployments that opted in)

(documented: encryption package)

The agent does not deserialize untrusted Java ObjectInputStream data from any in-model source

All in-model sources with their documented handlers

Demonstration that any in-model code path reaches ObjectInputStream.readObject() on attacker-controlled bytes

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.

11. Security properties Flume does not provide (§4.9)

  1. No authentication on the JSON/Prometheus HTTP metrics endpoint. The endpoint is by design unauthenticated and unencrypted. (documented: HTTPMetricsServer source has no auth or TLS code paths.) Operators must firewall the port.

  2. 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.

  3. 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.

  4. 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)

  5. 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.

  6. No defense against an attacker who controls headers used by sinks to choose output paths. HDFS path = /data/%{client}/log will route based on attacker-supplied client header; that is a §4.11 misuse, not a Flume property.

11.1. False-friend properties

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.

11.2. Well-known attack classes Flume does not defend against on its own

  1. 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.

  2. Header injection into headers that sinks treat as routing data. As above; the canonical case is HDFS path placeholders. (§4.11)

  3. Replay attacks. Re-sending captured Avro/Thrift frames will deliver duplicate events. The downstream is responsible for idempotency or de-duplication.

  4. Source-IP spoofing for UDP-based sources (SyslogUDPSource, NetcatUdpSource). Inherent to UDP; cannot be addressed at this layer.

  5. Resource exhaustion via many slow connections against TCP sources. Mitigations belong at the network / LB layer.

  6. 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).

12. Downstream responsibilities (§4.10)

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.

  1. 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.

  2. Enable TLS (ssl = true) on every network source that listens outside localhost.

  3. Firewall the monitoring port. It returns operational metadata with no authentication.

  4. If using the HTTP configuration provider, set HTTPS and basic-auth credentials. The configuration the agent fetches is fully privileged.

  5. 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.

  6. Treat flume.conf as 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.

  7. Validate operator-supplied inputs at the operator boundary. ExecSource commands, 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.

  8. Pin and review dependency versions when building from source. The dormant project does not commit to keeping transitive dependencies patched.

  9. Do not use Flume for audit logging without an independent integrity control on the audit pipeline (downstream signing, append-only storage with hash chaining).

  10. Do not place the agent inside an application that treats events as security-sensitive without independent authentication.

  11. 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.

13. Known misuse patterns (§4.11)

  1. Passing attacker-influenced event headers into HDFS / file-roll path templates. 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.

  2. Using NetcatSource for production traffic. Documented as for testing; no protocol framing, no flow control. Mitigation: use Avro or Syslog instead.

  3. Using ExecSource with tail -F on user-writable files. The source then trusts the contents of an operator-claimed-trusted file that is actually attacker-writable. Mitigation: Taildir plus filesystem ACLs.

  4. Wiring MemoryChannel between sources and sinks that the operator considers "reliable." Memory channel loses events on JVM crash by design. Mitigation: File channel for any reliability requirement.

  5. Running multiple agents on the same host with overlapping channel directories. File channel is single-writer; concurrent access corrupts state.

  6. 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.

  7. 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.

  8. Enabling the HTTP configuration provider without TLS or auth. The provider will then re-load any properties any attacker can serve to it.

  9. 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.

  10. 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.

14. Known non-findings — recurring false positives (§4.11a)

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.

  1. "`HTTPMetricsServer` has no authentication" → §4.9 / §4.10. By design; operator-firewalled. Disposition: BY-DESIGN: property-disclaimed.

  2. "`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.

  3. "`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 separate argv element, not shell-interpreted. Disposition: OUT-OF-MODEL: trusted-input.

  4. "Default ssl = false on AvroSource permits MITM" → §4.10. Operator must enable. Disposition: OUT-OF-MODEL: non-default-build (with the §4.5a maintainer ruling pending).

  5. "`MemoryChannel` loses data on crash" → §4.9. By design; channel choice is the operator’s. Disposition: BY-DESIGN: property-disclaimed.

  6. "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).

  7. "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, is OUT-OF-MODEL: unsupported-component for the dependency.

  8. "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.

  9. "`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.

  10. "`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.)

15. Conditions that would change this model (§4.12)

  1. Flume returns to ACTIVE status in Logging Services. Many of the "we will not patch dependencies" assumptions soften.

  2. 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.

  3. The default for any §4.5a knob flips (e.g., ssl becomes default-on).

  4. A configuration mechanism gains a remote, network-fetched mode without authentication by default (already the case for HTTP config provider — handled).

  5. A vulnerability report cannot be cleanly assigned to one of the §4.13 dispositions. That is evidence of a MODEL-GAP and the model must be revised before the report is closed.

  6. 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).

16. Triage dispositions (§4.13)

Disposition Meaning for Flume Licensed by

VALID

Violates a §4.8 property via an in-scope adversary and input. Reported per apache.org/security/. Outcome may be: an advisory only (no fix release), a fix on main, or in exceptional cases a new release if the PMC decides.

§4.8, §4.6, §4.7

VALID-HARDENING

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

OUT-OF-MODEL: trusted-input

Requires attacker control of a parameter the §4.6 table marks trusted. Closed with a citation to the row.

§4.6, §4.3

OUT-OF-MODEL: adversary-not-in-scope

Requires a capability §4.7 excludes (co-tenant, write-access to flume.conf, side-channel).

§4.7

OUT-OF-MODEL: unsupported-component

Lands in flume-ng-tests, in a *.template config sample, in log4j 1.x itself, or in a transitive dependency without a demonstrated reachable path.

§4.3

OUT-OF-MODEL: non-default-build

Only manifests with a knob the PMC has designated dev-only or operator-must-flip (per §4.5a).

§4.5a

BY-DESIGN: property-disclaimed

Concerns a property §4.9 explicitly does not provide (unauthenticated metrics, no constant-time, no MAC, etc.).

§4.9

KNOWN-NON-FINDING

Matches a documented entry in §4.11a.

§4.11a

MODEL-GAP

Cannot be routed to any of the above. Triggers a §4.12 revision before the report is closed.

§4.12

17. Open questions for the PMC (§4.14)

Grouped into waves of 3–7 per skill §3.2. Each question states a proposed answer for the PMC to confirm, correct, or strike.

17.1. Wave 1 — scope, dormant-posture, security envelope

  1. 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?

  2. Proposed: "An attacker with write access to flume.conf is out of model — equivalent to operator compromise." → §4.3, §4.7. Confirm?

  3. 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 is VALID and security-critical." → §4.8. Confirm; if so, is there any source/handler combination this does not cover?

  4. 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.

  5. Proposed: "Defaults that are less-secure (ssl = false, HTTP config provider auth = none, no Kerberos on HDFS sink) are operator-must-enable, not supported production posture — therefore findings against pure defaults are OUT-OF-MODEL: non-default-build." → §4.5a, §4.10, §4.13. Confirm? If the PMC disagrees on any of these, they become VALID.

  6. 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?

17.2. Wave 2 — environment, negative claims about host effects

  1. Proposed: "Flume does not install signal handlers beyond JVM defaults; does not fork()/exec() except via ExecSource / 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?

  2. 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.

  3. 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?

  4. Proposed: "`NetcatSource` is testing-only; a finding that requires a NetcatSource in production is OUT-OF-MODEL: unsupported-component or VALID-HARDENING at best." → §4.11. Confirm — or is Netcat considered a real production option somewhere?

  5. Proposed: "POSIX rename/atomicity is assumed by File channel and Taildir; non-POSIX filesystems are best-effort." → §4.5. Confirm?

17.3. Wave 3 — sinks, deserialization, false friends

  1. 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?

  2. Proposed: "Default JSON handler on HTTPSource does 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?

  3. 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?

  4. 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.

  5. 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?

17.4. Wave 4 — meta (publication and coexistence)

  1. Where does this document live? Proposed: docs/threat-model.adoc in the repo, linked from the README banner above the dormant notice. Confirm or pick alternative.

  2. Does a thin SECURITY.md get added that points to (a) this file and (b) apache.org/security/? Proposed: yes. Confirm.

  3. Versioning binding — proposed: "the model is tagged against main at 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.

  4. Sign-off process — proposed: a LAZY-CONSENSUS vote on dev@logging.apache.org once the wave-1/2/3 answers are folded in. Confirm.

18. Machine-readable companion (§4.15)

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)

19. Self-check status

  • ✓ 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment