--- /dev/null
+HAProxy Threat Model & Trust Boundaries
+
+This document defines the security boundaries of HAProxy, explicitly outlining
+what does and does not constitute a security vulnerability. Its purpose is to
+give reporters, developers and reviewers a single, predictable basis for
+judging an issue's real-world impact.
+
+The project's strong preference is to fix issues quickly and in the open.
+Public handling gets fixes to users sooner and spares the ecosystem
+(distributions in particular) the heavy cost of embargo coordination, which in
+practice has rarely served users. Private, coordinated disclosure is reserved
+for the few cases whose real-world impact genuinely warrants it, judged from
+the severity ordering (section 6) and the mitigations (section 5). An issue
+that is technically in scope but contained in practice does not, by itself,
+call for an embargo.
+
+These boundaries apply strictly to officially supported, documented builds
+running under a sane, production-ready configuration. Security guarantees are
+explicitly voided when using opt-in unsafe knobs, undocumented behavior, or
+experimental features. A configuration that merely lacks a recommended
+hardening step (for instance, no chroot) does not by itself move a
+client-triggered bug out of scope; the missing mitigation only widens the
+blast radius (sections 5 and 6).
+
+1. ASSETS TO PROTECT
+ HAProxy sits on the critical path of the services it fronts, so its
+ availability and the integrity and confidentiality of the configuration and
+ secrets it holds are all essential to protect. The assets below are not
+ ranked here; their relative severity is ranked in section 6.
+ - Integrity and confidentiality of the host and configuration: a compromise
+ of the network-facing worker must not extend to the filesystem, nor to the
+ configuration and its dependencies (private keys, Lua scripts, maps,
+ crt-lists, ACLs). On a properly configured system the default structural
+ mitigations prevent this, leaving only a compromise of the master process
+ as a residual path (see section 5).
+ - Confidentiality of long-lived secrets: TLS private keys and certificates
+ above all. Unlike transient client data, their disclosure is permanent and
+ systemic (impersonation and traffic decryption until every key is rotated
+ and revoked).
+ - Availability of the proxied service: being on the critical path, keeping
+ HAProxy serving is paramount. A small, cheap amount of attacker input
+ must neither consume a disproportionate amount of CPU or memory
+ (asymmetric DoS, see section 3) nor crash or stall the process.
+ - Confidentiality and isolation of client data: data belonging to one
+ connection, stream or client must never leak to another, and process
+ memory (including uninitialized memory) must never leak to a client.
+ - Process integrity (memory safety): no RCE, memory corruption or undefined
+ behaviour (UB) reachable from untrusted input.
+ - Correct enforcement of the configured policy: access controls, routing and
+ header manipulations decided by the configuration must not be bypassable
+ by crafted input.
+
+2. ATTACKER AND ENTRY POINTS
+ - The reference attacker is an untrusted client able to send arbitrary
+ bytes to a frontend: raw TCP payloads, HTTP/1, HTTP/2 and HTTP/3 (QUIC)
+ traffic, and arbitrary TLS handshake records.
+ - Entry points in scope are therefore the listeners and everything that
+ parses or transforms client-supplied data: TLS, the HTTP muxes, HTX,
+ header/URL processing, sample fetches and converters acting on request
+ data, stick-tables fed by client data, the cache, and the QUIC/H3 stack.
+ - A secondary untrusted source is the DNS resolver path: even though
+ nameservers are configured, their answers arrive over UDP and can be
+ spoofed by an off-path attacker, so the response parser handles
+ attacker-influenced input.
+
+3. WHAT QUALIFIES AS A SECURITY BUG (IN SCOPE)
+ - Memory-safety issues (overflow, out-of-bounds, use-after-free, type
+ confusion, UB) reachable from untrusted client input.
+ - Cross-client or cross-stream effects: HTTP request smuggling, response
+ splitting, cache poisoning, and any mixing of data between concurrent
+ streams or connections (notably in the H2/H3 multiplexers).
+ - Disclosure of process memory or of another client's data to a client.
+ - Bypass of a policy that the configuration is meant to enforce (e.g.
+ defeating an http-request deny/acl through request crafting).
+ - Asymmetric / algorithmic denial of service: a single or a few cheap
+ requests causing disproportionate CPU or memory usage (hash-collision
+ flooding, catastrophic regex backtracking, quadratic parsing, unbounded
+ allocation, etc). This is distinct from volumetric DoS (see 4).
+ - Misuse of a third-party library on untrusted input: feeding malformed
+ client data into OpenSSL, PCRE, Lua, zlib, etc. in a way that corrupts
+ memory or crashes the process is in scope. A vulnerability inside the
+ library itself is handled by that library's project, not here.
+ - Mishandling of spoofable DNS responses: memory corruption, crashes or
+ cache/state poisoning in the resolver caused by a crafted DNS answer are
+ in scope, despite nameservers being nominally trusted (see section 2).
+
+4. WHAT DOES NOT QUALIFY (OUT OF SCOPE)
+ The following do not fall into the security-bug category.
+
+ Trusted peers, servers and protocols:
+ - attacks that require a non-compliant or malicious server: in a reverse
+ proxy, servers are trusted, or ejected. This covers server-to-client
+ attacks in general.
+ - attacks on protocols only used with trusted peers: peers, PROXY protocol,
+ CIP (NetScaler Client-IP insertion), SOCKS, a local server reached over
+ an ABNS or UNIX socket, an FCGI server, etc., as well as TLS servers
+ contacted by the internal httpclient.
+ - malfunction of a trusted auxiliary service (log server, ring output,
+ CLI API consumer, etc.).
+
+ Privileged or local access (the actor is already trusted):
+ - any problem triggered through admin access to the CLI.
+ - anything requiring access to the master CLI.
+ - anything requiring access to the command line.
+ - anything requiring write access to the configuration file or any of its
+ dependencies (Lua scripts, certificates, crt-list, acl, map, etc.).
+ - anything requiring a configuration running as root, or chrooted to "/"
+ (i.e. with no effective chroot).
+
+ Opt-in unsafe or experimental knobs (the operator disabled a safety):
+ - anything requiring "experimental-mode on" on the CLI.
+ - anything requiring "insecure-fork-wanted".
+ - anything requiring "accept-unsafe-violations-*".
+ - anything requiring "expose-experimental-directives".
+
+ Misconfiguration:
+ - anything requiring a configuration that emits warnings at boot.
+ - anything requiring a nonsensical configuration, e.g. a server looping back
+ to the frontend, non-standard header processing or URL rewriting, or an
+ excessively large number of headers or excessively large header/body
+ sizes.
+
+ Volumetric or otherwise detectable activity:
+ - anything requiring such a high and sustained level of activity that it
+ would be detected and blocked in production (e.g. billions of requests or
+ connections). This is volumetric DoS, as opposed to the asymmetric DoS of
+ section 3.
+
+ Inherent protocol limitations:
+ - anything that is a limitation of a standard protocol rather than an
+ implementation flaw. For example, HTTP/1 has no way to abort a single
+ transfer without closing the connection, so a client aborting a transfer
+ will necessarily cause the corresponding server-side connection to be
+ closed; this is by design of the protocol, not a vulnerability.
+
+ Features that are not security boundaries:
+ - the stats page, including its admin mode, relies on HTTP basic
+ authentication and was never meant to be a security boundary. Exposing a
+ public-facing, admin-enabled stats page is therefore not covered.
+ - configuring a listener to accept the PROXY protocol or CIP from senders
+ that are not restricted to trusted ones is a misconfiguration: these
+ headers are believed on trust, so the listener must be reachable only by
+ the trusted L4/L7 component that prepends them.
+
+ Side channels:
+ - cryptographic and micro-architectural side channels (timing, cache,
+ speculative execution, etc.) are out of scope. Constant-time handling of
+ secrets is pursued on a best-effort basis as ordinary hardening where it
+ clearly matters, but observable timing or resource variations are not
+ handled as security bugs.
+
+ Log integrity:
+ - escaping of data emitted to logs is a configuration responsibility.
+ Injection of control characters or forged fields through logged client
+ data (e.g. when default escaping is disabled, or when a downstream log
+ consumer mis-parses) is not covered.
+
+5. DEFENSE IN DEPTH (DEFAULT HARDENING)
+ A correctly deployed HAProxy combines several built-in mitigations that
+ bound the impact of a successful compromise. These are deliberately taken
+ into account when assessing the real-world severity of an issue and the
+ handling it deserves: when one of them contains the practical impact of a
+ bug, that bug rarely warrants a coordinated embargo and is usually better
+ fixed quickly and in the open, where users get the fix sooner. They lower
+ severity, not the obligation to fix: an exploitable memory-safety bug
+ reachable from client input is still corrected as a bug.
+ - No fork()/exec() in the worker: the worker never forks nor runs external
+ programs, so an attacker who achieves code execution has little ability
+ to spawn a shell or launch persistent background code. ("insecure-fork-
+ wanted" deliberately disables this and is itself out of scope, see
+ section 4.)
+ - chroot and privilege drop: in the sane configuration this document
+ assumes, the worker drops to an unprivileged user/group and chroots into
+ an empty, unwritable directory. Injected code therefore has no filesystem
+ access and very limited means to act on the host.
+ - Activity watchdog: a thread that stops making progress, e.g. hijacked
+ into an attacker-controlled loop or otherwise stuck, no longer services
+ the event loop; the watchdog detects this lack of activity and kills the
+ process after a few seconds rather than letting it be silently held.
+ - Master/worker separation: only the worker is exposed to the network and
+ runs the parsers reachable by clients, and it is the unprivileged,
+ chrooted process. The master keeps privileges and filesystem access but
+ has no network exposure. The master must therefore be protected as the
+ trusted, more privileged component; an attacker is assumed to face only
+ the worker. The master must under no circumstances be reachable from the
+ worker (e.g. a master CLI bound to a TCP socket such as localhost is
+ trivially reachable from compromised worker code and defeats this critical
+ separation).
+
+6. SEVERITY ORDERING
+ The worst-case outcomes below are ranked by their realistic impact on a
+ standard configuration, from most to least severe, and the effort spent
+ guarding against each is proportional to that severity. The ranking reflects
+ the master/worker privilege split and the containment provided by the
+ section-5 mitigations.
+ 1. Remote code execution in the master process. The master is privileged
+ and has filesystem access, so compromising it defeats every
+ containment, leaks every secret, and can subvert or take down the
+ whole service.
+ 2. Chosen disclosure of long-lived secrets, TLS private keys and
+ certificates above all. Unlike an outage the damage is permanent and
+ silent: stolen keys allow impersonation, interception and, absent
+ forward secrecy, decryption of captured traffic, until every affected
+ key is rotated and revoked across the ecosystem; a restart does not
+ undo it. "Chosen" sets this rank, not scope: any disclosure of process
+ memory or of another client's data to a client is in scope (section 3);
+ this top rank is reserved for a targeted exfiltration, where the
+ attacker steers the read to a known secret. A leak that cannot be
+ steered toward a specific secret is still an in-scope disclosure bug,
+ but ranks far lower - often no worse than the crash such a read tends
+ to cause first.
+ 3. Crash of the master process. It brings the entire service down and
+ prevents workers from being respawned: a full but recoverable outage.
+ 4. Crash of the worker process. A transient outage: in-flight connections
+ are lost and traffic is interrupted for the fraction of a second it
+ takes to respawn.
+ 5. Remote code execution in the worker process. Contained by no-fork,
+ chroot, privilege drop and the watchdog, its availability impact is
+ usually below a worker crash, except in the unlikely case where it
+ unlocks the chosen disclosure of level 2, which is hard to reach
+ through the internals from injected code.
+ 6. Policy bypass. Serious, but with no direct availability impact.
+
+7. SECURITY-RELEVANT INVARIANTS AND DEFAULTS
+ The values below define the conditions HAProxy is designed to operate
+ within, and may be relied upon by parsing and processing code. A suspected
+ vulnerability that can only be triggered by conditions outside them
+ (typically values pushed beyond the stated limits) does not qualify as
+ security-relevant:
+ - trash buffers and struct buffer storage are always at least a few kB.
+ - default buffer size is 16 kB (15 kB max input, as 1 kB is reserved for
+ rewrites), tunable up to <256 MB.
+ - default log line is 1 kB, tunable up to <=64 kB.