blob: 0627637417d6ab6e5a827faf2c7dca64a4830a69 [file] [view]
<!--
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
# Threat Model — Apache Directory (umbrella)
## §1 Header
- **Project:** Apache Directory — a family of identity-infrastructure components: an **LDAP v3 directory
server** (ApacheDS), the **LDAP API** client/codec library, a **Kerberos** implementation (Kerby, incl.
KDC + token/PKINIT preauth), the **Fortress** RBAC/ARBAC authorization system (core + REST endpoint +
web console + container realm), a **SCIM 2.0** provisioning implementation (SCIMple), an **MVCC B-tree**
storage engine (Mavibot), and the **Studio** desktop LDAP client *(documented — project; per-repo READMEs)*.
- **Scope of this umbrella:** the **shared trust model** across the server-side identity components, with
**per-domain addenda** where the surface diverges (LDAP bind/ACI, Kerberos KDC crypto, RBAC policy, SCIM
protocol, MVCC storage). The Studio desktop client is modelled lightly as a *client* (§3).
- **Repos covered (confirmed scope):** `directory-server`, `directory-ldap-api`, `directory-kerby`,
`directory-fortress-core`, `directory-fortress-enmasse`, `directory-fortress-commander`,
`directory-fortress-realm`, `directory-scimple`, `directory-mavibot`, `directory-studio`.
- **Modelled against:** each repo's default branch HEAD (2026-05-31).
- **Status:** **DRAFT — v0, not yet reviewed by the Directory PMC.** Produced by the ASF Security team via the
`threat-model-producer` rubric (<https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573>).
- **Reporting / version-binding / legend** as in the sibling models. **Draft confidence:** ~18 documented /
0 maintainer / ~70 inferred. Each *(inferred)* routes to §14 (grouped by domain).
These components share one shape: a **network service that authenticates a remote principal and then
authorizes its requests over a wire protocol** (LDAP, Kerberos, SCIM/HTTP, Fortress REST). The umbrella
captures that shared boundary; the addenda capture each protocol's specific attack surface.
## §2 Scope and intended use
Caller roles (common across the stack):
- **Unauthenticated network client** — a peer speaking LDAP/Kerberos/HTTP before authenticating; untrusted.
- **Authenticated principal** — bound LDAP user, Kerberos principal, or authenticated SCIM/REST caller;
trusted up to its directory/RBAC permissions.
- **Administrator** — a principal with directory-admin / Kerberos-admin / Fortress-superuser rights.
- **Operator / deployer** — controls server config, schema, ACIs, the Kerberos realm + keytabs, the RBAC
policy data, TLS material, and the backing store. **Trusted; out of model as adversary (§3).**
**Component-family table (repo → domain → model placement):**
| Repo | Domain / role | Trust surface | In runtime model? |
| --- | --- | --- | --- |
| `directory-server` (ApacheDS) | LDAP v3 server (bind, search, modify, ACI), embeds Kerberos/DNS | LDAP/Kerberos network protocol | **Yes — host of this umbrella** |
| `directory-ldap-api` | LDAP protocol API + ASN.1/BER codec (client & server) | parses untrusted LDAP PDUs | **Yes** |
| `directory-kerby` | Kerberos: KDC (AS/TGS), client, crypto, PKINIT/token preauth | Kerberos network protocol; crypto | **Yes (addendum K)** |
| `directory-fortress-core` | RBAC/ARBAC policy engine over LDAP | API + policy decisions | **Yes (addendum F)** |
| `directory-fortress-enmasse` | Fortress REST service (RBAC over HTTP) | HTTP/REST | **Yes (addendum F)** |
| `directory-fortress-commander` | Fortress web admin console | HTTP/web UI | **Yes (addendum F)** |
| `directory-fortress-realm` | Fortress container security realm (Tomcat/etc.) | servlet auth integration | **Yes (addendum F)** |
| `directory-scimple` | SCIM 2.0 provisioning protocol | HTTP/JSON | **Yes (addendum S)** |
| `directory-mavibot` | MVCC B-tree storage engine (a backend) | in-process; on-disk data | **Yes (addendum M)** |
| `directory-studio` | Eclipse-based LDAP **client** tool (desktop) | parses server responses; local | Light — client tool (§3) |
## §3 Out of scope (explicit non-goals)
- **The operator/deployer as adversary**, and pure misconfiguration (weak ACIs, an open anonymous bind left
enabled, a Kerberos realm with weak crypto enabled, RBAC policy mistakes, TLS disabled). Each component
provides controls; configuring them is the operator's job (§10/§11) *(inferred)*.
- **The backing data stores and external systems** the components integrate with (an external LDAP, an
external KDC, the OS keytab/credential cache), except as these components consume them.
- **`directory-studio` as a server** — it is a desktop client; its in-model surface is *parsing untrusted
responses* from a directory it connects to, not serving requests. Findings requiring a malicious server
the user chose to connect to are low-priority client-side hardening, not server-side `VALID`.
- **Examples, samples, integration-test harnesses, and build tooling** across all repos *(inferred)*.
- **Cryptographic-primitive internals** (the JCE provider) except as the components select and use them.
## §4 Trust boundaries and data flow
The shared boundary is **the wire-protocol request before authentication+authorization completes**. Per domain:
- **LDAP (server, ldap-api):** the BER/ASN.1 decoder is the first thing untrusted bytes hit — a classic
parser/DoS surface. After a **bind** establishes identity (simple/SASL), **ACIs** authorize each
operation; anonymous/unauthenticated operations are a configurable surface *(inferred — addendum L)*.
- **Kerberos (kerby):** AS-REQ/TGS-REQ from any network peer reach the KDC; pre-authentication, ticket
issuance, encryption-type negotiation, and PKINIT/token preauth are the trust transitions; the KDC's
master key and per-principal keys are the crown jewels *(inferred — addendum K)*.
- **Fortress (core/enmasse/commander/realm):** RBAC/ARBAC **policy decisions** are the boundary — a request
is authorized only if the activated roles grant the permission; the REST/web tiers add HTTP auth, CSRF,
and injection surfaces *(inferred — addendum F)*.
- **SCIM (scimple):** HTTP/JSON provisioning requests (create/modify/delete users/groups) must be
authenticated and authorized; the filter/PATCH parsers are an injection/DoS surface *(inferred — addendum S)*.
- **Mavibot (storage):** consumes data from the server layer; its trust input is the on-disk B-tree and the
records the server hands it — corruption-resistance and bounds, not a network boundary *(inferred — addendum M)*.
**Reachability precondition (shared):** a finding is in-model on a **server inbound** path if reachable from
an unauthenticated or under-privileged remote principal *before* the component's auth/authorization gate;
a finding that requires admin rights or a misconfiguration is `OUT-OF-MODEL` (§7/§5a).
## §5 Assumptions about the environment
- JVM services; operator-managed config, schema, ACIs, Kerberos realm/keytabs, RBAC policy, and TLS material.
- Backing storage (Mavibot or another partition backend; LDAP for Fortress policy) is on trusted disk.
- Clocks are synchronized within the Kerberos skew window *(inferred — addendum K)*.
- TLS/StartTLS, SASL, and Kerberos crypto are available and operator-configured *(inferred)*.
- **What the stack does to its host (*(inferred)* — wave-2):** binds protocol ports; reads/writes its data
partitions and keytabs; performs crypto; the Fortress tiers open HTTP listeners and bind to a backing LDAP.
Not assumed to execute host commands.
## §5a Build-time and configuration variants
| Knob (per domain; defaults *(inferred)*) | Effect | Ruling needed |
| --- | --- | --- |
| LDAP **anonymous bind / unauthenticated access** | Whether unauthenticated reads/ops are allowed | **Open (wave-1, L):** default on/off; supported posture? |
| LDAP **ACI default** & admin-limits | Default authorization posture | **Open (L)** |
| Kerberos **allowed enctypes** (incl. legacy RC4/DES) | Crypto strength of tickets | **Open (wave-1, K):** are weak enctypes disabled by default? |
| Kerberos **PKINIT / token-preauth** enabled | Adds preauth attack surface | Open (K) |
| Fortress **REST/console auth + TLS** | Whether RBAC management is authenticated/encrypted | **Open (wave-1, F)** |
| SCIM **auth + filter/PATCH limits** | Auth + injection/DoS posture | **Open (wave-1, S)** |
| TLS/StartTLS enforcement (all protocols) | Transport confidentiality/integrity | Operator (§10) |
## §6 Assumptions about inputs (shared trust table)
| Entry point | Parameter | Attacker-controllable? | Caller/operator must enforce |
| --- | --- | --- | --- |
| LDAP listener | BER-encoded PDU (bind, search filter, DN, controls) | **yes** | codec bounds; filter complexity limits; ACI authz |
| Kerberos KDC | AS-REQ/TGS-REQ (princ names, enctypes, preauth, PA-DATA) | **yes** | enctype policy; preauth; replay window |
| SCIM endpoint | HTTP method, JSON body, SCIM filter, PATCH ops | **yes** | authn/authz; filter/PATCH bounds; JSON limits |
| Fortress REST/console | HTTP request, RBAC operands, form fields | **yes** | authn; RBAC decision; CSRF; injection guards |
| LDAP-API codec | server/client LDAP messages | **yes** (both directions) | robust decode; no OOB/DoS |
| Mavibot | record bytes from the server; on-disk pages | from a **trusted** server layer | bounds; corruption handling |
| config / schema / ACI / keytab / policy | all | **no — operator-trusted** | never sourced from a request |
## §7 Adversary model
- **Primary adversary:** an untrusted network client of any listener (LDAP, Kerberos, SCIM, Fortress REST/UI)
— sending crafted PDUs, malformed/oversized requests, weak-enctype or replayed Kerberos requests,
injection payloads (LDAP filter, SCIM filter, SQL/LDAP injection via the management tiers), or
authentication-bypass attempts.
- **Secondary:** an **under-privileged authenticated principal** attempting to exceed its ACIs / RBAC roles
(privilege escalation); a malicious LDAP server vs. a Studio/ldap-api **client**.
- **Goals:** authenticate as another principal / bypass bind; read or modify directory entries, Kerberos
principals, or RBAC policy beyond authorization; forge or replay Kerberos tickets; crash/DoS a service;
corrupt stored data.
- **Out of model:** the operator; anyone holding the KDC master key, admin DN, Fortress superuser, keytabs,
or filesystem access; the JCE/OS internals.
## §8 Security properties the project provides (shared + per-domain)
*(All *(inferred)* pending §14; symptom + severity per the rubric.)*
1. **Authentication integrity (shared).** Bind / Kerberos preauth / SCIM+REST auth verify the principal before
privileged operations *(inferred)*. *Symptom:* auth bypass. *Severity:* critical.
2. **Authorization enforcement (shared).** LDAP **ACIs**, Fortress **RBAC/ARBAC**, and SCIM authz confine a
principal to permitted operations *(documented — Fortress is an RBAC engine; ACI in ApacheDS; specifics
inferred)*. *Symptom:* read/modify beyond authorization; role/permission escalation. *Severity:* critical.
3. **Robust protocol parsing (shared).** The LDAP BER codec, Kerberos ASN.1, and SCIM JSON/filter parsers
reject malformed/oversized input cleanly rather than crashing or corrupting memory *(inferred)*. *Symptom:*
crash/hang/OOB/DoS from crafted input. *Severity:* high–critical.
4. **(K) Kerberos ticket integrity & replay resistance.** Tickets are bound to the issuing key and protected
by timestamps/replay caches; weak enctypes are restrictable *(inferred)*. *Symptom:* forged/replayed
ticket; downgrade to weak crypto. *Severity:* critical.
5. **(M) Storage integrity.** Mavibot's MVCC keeps readers consistent and resists corruption from concurrent
writes / crash *(inferred — MVCC design)*. *Symptom:* reader sees torn/inconsistent state; corruption.
*Severity:* high.
6. **Transport security support.** TLS/StartTLS and SASL confidentiality/integrity when configured *(inferred)*.
*Symptom:* MITM/downgrade where protection was expected. *Severity:* high.
## §9 Security properties the project does NOT provide
- **No security without configuration** — anonymous LDAP, weak Kerberos enctypes, or an unauthenticated
Fortress REST/console expose the service to the extent the operator left them open *(inferred)*.
- **No defence against the operator / key-holder** (KDC master key, admin DN, Fortress superuser) — §3.
- **No application-level authorization beyond the configured ACIs/RBAC policy.**
- **(client) ldap-api / Studio do not protect the user against a hostile server they chose to connect to**
beyond robust parsing.
**False friends:**
- *A successful **anonymous bind** looks like "it works" but is unauthenticated access* — many reports are
really an operator leaving anonymous access on.
- *Kerberos "encryption" of a ticket is integrity/authenticity, not a guarantee against a weak **enctype**
the realm still permits* — a permitted RC4/DES enctype is a downgrade surface.
- *An RBAC **role assignment** is not active permission until the session **activates** the role* (RBAC vs.
ARBAC, separation-of-duty constraints) — naive "user has role" checks miss SoD/DSD.
- *An LDAP **search filter** is a query language, not inert data* — filter injection via unsanitized input at
a downstream app is the LDAP analogue of SQL injection.
**Well-known attack classes to keep in view:** LDAP/SCIM **filter injection**; **anonymous-bind** exposure;
Kerberos **enctype downgrade**, **replay**, **Kerberoasting** (weak service keys), **PKINIT** edge cases;
**ASN.1/BER parser DoS**; **XXE/JSON-bomb** in SCIM/REST; **CSRF/XSS** in the Fortress console; **SoD/DSD**
policy bypass in RBAC; **password-policy / lockout** bypass.
## §10 Downstream (operator) responsibilities
- **LDAP:** disable anonymous/unauthenticated access unless intended; set restrictive ACIs and admin limits;
enforce TLS/StartTLS; bound search filter complexity and result sizes.
- **Kerberos:** disable weak enctypes (RC4/DES); require preauth; protect the KDC master key + keytabs; keep
clocks synced and the replay cache on.
- **Fortress:** authenticate and TLS-protect the REST endpoint and web console; protect the policy LDAP;
configure SoD/DSD constraints deliberately.
- **SCIM:** require authentication/authorization on every endpoint; bound filter/PATCH/JSON size.
- **Storage:** protect the data partitions/keytabs at the filesystem layer; back up.
- Track ASF advisories and stay on supported lines.
## §11 Known misuse patterns
- Leaving anonymous LDAP bind/read enabled on an exposed server.
- Permitting legacy Kerberos enctypes for "compatibility".
- Exposing the Fortress REST endpoint or console without authentication/TLS.
- Building LDAP/SCIM filters by concatenating untrusted input in a downstream app (filter injection).
- Treating an RBAC role *assignment* as an active permission, ignoring activation/SoD.
## §11a Known non-findings (recurring false positives)
*(v0 seed — the PMC (LDAP/Kerberos/RBAC experts) will own the authoritative list — §14.)*
- **"Anonymous bind allowed" / "weak enctype available"** against a default/sample config — operator posture
(§5a/§10); `OUT-OF-MODEL: non-default-build` unless the *default* is the insecure one (then `VALID` — §14).
- **"Admin can do X"** — the admin/superuser is trusted (§7); an authorized admin action is not a finding.
- **LDAP/SCIM filter injection attributed to a downstream caller** concatenating input — not a server bug (§9).
- **Findings in examples / integration tests / build tooling** across repos — out of scope (§3).
- **Studio parsing a response from a server the user connected to** — client-side hardening, not server `VALID` (§3).
- **Mavibot internal invariants** not reachable from server-accepted input — out of the input surface (§6).
## §12 Conditions that would change this model
- A change to a default auth/anonymous/enctype/anonymous-REST posture in any component.
- A new protocol surface, a new Kerberos preauth mechanism, or a new SCIM/REST endpoint enabled by default.
- A change to ACI/RBAC default semantics or to Mavibot's consistency guarantees.
- Promotion of `directory-studio` to a server role.
- Any report not cleanly routable to a §13 disposition.
## §13 Triage dispositions
| Disposition | Meaning | Licensed by |
| --- | --- | --- |
| `VALID` | Violates a claimed property via an in-scope adversary/input in a default/secure config. | §8, §6, §7 |
| `VALID-HARDENING` | No §8 property broken, but a §11 misuse is easy enough to warrant a safer default/guard. | §11 |
| `OUT-OF-MODEL: trusted-input` | Requires control of config / schema / ACI / policy / keytab. | §6 |
| `OUT-OF-MODEL: adversary-not-in-scope` | Requires operator / admin / key-holder capability. | §7, §3 |
| `OUT-OF-MODEL: unsupported-component` | Lands in examples, tests, build tooling, or Studio-as-server. | §3 |
| `OUT-OF-MODEL: non-default-build` | Only when an insecure non-default option was enabled. | §5a |
| `BY-DESIGN: property-disclaimed` | Concerns a §9-disclaimed property (no security without config; client ≠ server). | §9 |
| `KNOWN-NON-FINDING` | Matches a §11a entry. | §11a |
| `MODEL-GAP` | Routes to none of the above → revise the model. | §12 |
## §14 Open questions for the maintainers (grouped by domain)
**Wave 1 — insecure-default rulings across the stack (decide VALID-vs-misconfig):**
1. **(LDAP)** Is **anonymous bind / unauthenticated access** off by default, and is leaving it on an operator
choice (→ misconfig) rather than a default we ship? *Proposed:* off by default; on = operator choice.
2. **(Kerberos)** Are **weak enctypes (RC4/DES)** disabled by default and is **preauth required** by default?
*Proposed:* weak enctypes off; preauth required.
3. **(Fortress/SCIM)** Do the **REST endpoint, web console, and SCIM endpoints require authentication (+ TLS)**
by default? *Proposed:* yes; unauthenticated exposure is operator misconfig.
**Wave 2 — authorization & protocol parsing (§8):**
4. **(LDAP)** What enforces **ACI** authorization and are there bounds on **search-filter complexity / result
size** to prevent DoS? *Proposed:* ACI subsystem enforces; admin limits bound cost.
5. **(RBAC)** Does Fortress enforce **role activation + SoD/DSD** (not just assignment) on every decision?
*Proposed:* yes; activation + SoD enforced.
6. **(codec)** Are the **LDAP BER and Kerberos ASN.1 decoders** hardened against malformed/oversized PDUs
(depth/length caps)? *Proposed:* yes, bounded.
**Wave 3 — crypto, storage, §11a (§8/§9/§11a):**
7. **(Kerberos)** Replay protection + master-key handling assumptions; any known PKINIT/token-preauth caveats?
8. **(Mavibot)** What consistency/corruption guarantees does the MVCC engine make under crash/concurrent write?
9. **(all)** From the long advisory history, what do scanners most often (re)report that the PMC considers a
**non-finding** today? (Seeds §11a per domain.)
**Meta:**
10. Confirm the umbrella shape: this document in `apache/directory-server`, the other nine repos carrying an
`AGENTS.md`→`SECURITY.md`→(this umbrella) discoverability pointer, with the per-domain addenda above
expanded as the PMC answers. Should **Kerby / Fortress / SCIMple** instead each carry their *own* full
model (they are semi-independent products)? *Proposed:* umbrella + pointers now; split out later if the
PMC prefers.
## §15 Machine-readable companion
Deferred for v0; a `threat-model.yaml` per domain can later encode the §6 trust tables, §2/§3 scoping, §8
property rows, §9 false friends, §11a non-findings, and §13 dispositions.