Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions THREAT_MODEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
- **Version binding:** versioned with the project; a report against version *N* is triaged against the model as it stood at *N*.
- **Reporting cross-reference:** §8-property violations → report privately per the ASF process (`security@apache.org` → `private@drill.apache.org`); §3/§9 findings are closed citing this document.
- **Provenance legend:** *(documented)* = Drill's own docs/repo; *(maintainer)* = confirmed by a Drill PMC member through this process; *(inferred)* = reasoned from architecture/docs, not yet PMC-ratified — each has a matching §14 open question.
- **Draft confidence:** ~10 documented / 2 maintainer / ~26 inferred (cgivre's PR #3052 review folded: `contrib/` plugins in scope + the storage-enumeration non-finding).
- **Draft confidence:** ~10 documented / 3 maintainer / ~25 inferred (cgivre's PR #3052 review folded: `contrib/` plugins in scope + the storage-enumeration non-finding; 2026-10: `CREATE FUNCTION USING JAR` / `CREATE DAFFODIL SCHEMA USING JAR` staging-area precondition).

**What Drill is.** Apache Drill is a **schema-free, distributed SQL query engine** for large-scale datasets. A cluster of **Drillbit** daemons (coordinated via Apache ZooKeeper) accepts ANSI-SQL queries over JDBC, ODBC, a REST API, and a Web UI (default port **8047**), and executes them directly against data in configurable **storage plugins** (local/HDFS/S3 files, Hive, HBase, Kafka, MongoDB, RDBMS via JDBC, HTTP, …) — discovering schema at query time rather than requiring a pre-defined schema. *(documented — drill.apache.org)*

Expand Down Expand Up @@ -56,7 +56,7 @@ Intended deployment: a **clustered set of Drillbits** inside an operator-control
## §3 Out of scope (explicit non-goals)

- **The security of the underlying data sources.** HDFS/S3 permissions, the RDBMS behind the JDBC plugin, Hive authorization, the Kafka cluster — each enforces its own access control. Drill assumes them; it is not responsible for their misconfiguration. *(inferred — §14 Q2)*
- **Dynamic UDFs and storage-plugin configuration as code/connectivity execution.** Uploading a UDF jar or configuring a storage plugin is an **authorized admin operation**; the code/connection runs with the Drillbit's privileges. This is a feature, not a sandbox escape — `BY-DESIGN`. A finding that requires admin rights to register a UDF or add a plugin is out of model. *(documented — admin function; §14 Q4 confirms the trust line)*
- **Dynamic UDFs and storage-plugin configuration as code/connectivity execution.** Uploading a UDF jar or configuring a storage plugin is an **authorized admin operation**; the code/connection runs with the Drillbit's privileges. This is a feature, not a sandbox escape — `BY-DESIGN`. A finding that requires admin rights to register a UDF or add a plugin is out of model. *(documented — admin function; §14 Q4 confirms the trust line)* For dynamic UDFs specifically, `CREATE FUNCTION USING JAR` only *registers* a jar that is already present in the UDF staging area (`drill.exec.udf.directory.staging`); the SQL statement cannot upload content. Placing a jar there requires write access to the Drill cluster's filesystem, which is the real trust gate (§11a). The same holds for DFDL schemas: `CREATE DAFFODIL SCHEMA USING JAR` only registers a jar already in `drill.exec.daffodil.directory.staging`, and the Daffodil format's `schemaURI`/`schemaFile` come from admin-only format config. *(maintainer — cgivre, 2026-10)*
- **An operator with cluster/root access, the Drillbit service account, or direct ZooKeeper write access.** Anyone who controls the cluster processes or the coordination store has already won. `OUT-OF-MODEL: adversary-not-in-scope`. *(inferred — §14 Q5)*
- **Embedded / single-user mode**, where the caller owns the JVM, the filesystem, and all input — equivalent to an in-process library call. *(inferred — §14 Q1)*
- **SQL injection in an embedding application** that string-concatenates untrusted input into Drill SQL — that is the embedding app's bug, not Drill's. *(inferred — §11)*
Expand Down Expand Up @@ -133,6 +133,7 @@ The security envelope is set primarily by runtime configuration, not compile fla
- **Enable authentication and impersonation** before exposing Drill to more than one trusted user; do not run a multi-user cluster with the shipped auth-off / impersonation-off defaults. *(inferred — §14 Q9)*
- **Lock down the Web UI / REST (`:8047`)** — it can configure storage plugins and upload UDFs; restrict it to admins and protect it with auth + TLS.
- **Restrict who can configure storage plugins and upload dynamic UDFs** to trusted admins (these are code/connectivity-execution surfaces).
- **Restrict write access to the UDF staging area** (`drill.exec.udf.directory.staging`, on `drill.exec.udf.directory.fs`). Write access there is equivalent to code execution on every Drillbit once any user runs `CREATE FUNCTION USING JAR`. Set `exec.udf.enable_dynamic_support = false` if dynamic UDFs are not needed. Apply the same restriction to the Daffodil schema staging area (`drill.exec.daffodil.directory.staging`, on `drill.exec.daffodil.directory.fs`).
- **Configure wire encryption** (SASL/SSL) on client↔Drillbit and inter-Drillbit links on untrusted networks.
- **Network-isolate** the Drillbit cluster + ZooKeeper from untrusted networks; give data-source credentials least privilege.

Expand All @@ -152,6 +153,7 @@ The security envelope is set primarily by runtime configuration, not compile fla
- **"The REST API / Web UI accepts requests without authentication."** Only when auth is disabled — a non-default/operator-chosen posture (pending §14 Q9), not a Drill defect. `OUT-OF-MODEL: non-default-build`.
- **"A query can read an arbitrary local file via the `dfs` plugin."** In-model only if it crosses the impersonated identity's authorization or the configured workspace; otherwise it is the operator's plugin-scope choice. *(inferred — §14 Q2/Q7)*
- **"Drill can enumerate / read the files, schemas, or storage systems it is pointed at."** That is the **function** of a federated query engine — exposing configured storage to SQL is the point of Drill, not a vulnerability. `KNOWN-NON-FINDING` / `BY-DESIGN`. In-model **only** if the access crosses the authenticated identity's authorization (reading data an impersonated user shouldn't, or bypassing a Drill view — §8.2). *(maintainer — cgivre, PR #3052: "yes… that's the point of Drill".)*
- **"`CREATE FUNCTION USING JAR` / `CREATE DAFFODIL SCHEMA USING JAR` lets a user load a malicious jar or DFDL schema."** Recurring report. Neither statement uploads anything: each only registers a jar that already sits in its staging area on the cluster filesystem (UDF: `drill.exec.udf.directory.staging`, binary + sources; Daffodil: `drill.exec.daffodil.directory.staging`). `CreateFunctionHandler` and `CreateDaffodilSchemaHandler` fail if the file is missing. To exploit it, the attacker must already have write access to that filesystem location, i.e. filesystem/cluster access the model already treats as having won (§3, §7). `OUT-OF-MODEL: adversary-not-in-scope`. In-model **only** if a low-privilege client can get attacker-controlled bytes into the staging area through Drill itself (e.g. a `CTAS`/export or REST path that writes into either staging directory), which would be a `VALID` §8.3 break. Pointing the Daffodil format at an arbitrary `schemaURI` is format config, i.e. admin-tier (`OUT-OF-MODEL: trusted-input`). *(maintainer — cgivre, 2026-10)*
- **"SQL injection in Drill"** where the untrusted string was concatenated by an *embedding app* — that app's bug (§11), not Drill's.
- **Dependency-tail CVEs** (Calcite, Hadoop, Jackson, Netty, a transitive jar) from an SCA scan — triage upstream unless Drill's own code reaches the vulnerable path with untrusted input.

Expand Down Expand Up @@ -182,7 +184,7 @@ The security envelope is set primarily by runtime configuration, not compile fla

- **Q1.** Confirm the in-scope surface is "an authenticated SQL/REST client at the Drillbit front door (JDBC/ODBC/REST/Web UI), in a clustered multi-user deployment", with embedded single-user mode out of scope. Anything to add?
- **Q2.** Confirm Drill is *not* responsible for the underlying data sources' own access control — that HDFS/S3/RDBMS/Hive/Kafka security is theirs, and Drill's job is to honor it (via impersonation/views), not replace it.
- **Q4.** Confirm dynamic-UDF upload and storage-plugin configuration are **admin-only, code/connectivity-execution-by-design** — i.e. a finding that requires those rights is out of model.
- **Q4.** *(Partially answered — cgivre, 2026-10: `CREATE FUNCTION USING JAR` and `CREATE DAFFODIL SCHEMA USING JAR` require the jar to be pre-placed in a staging area, so filesystem write access is the gate; folded into §3/§10/§11a.)* Confirm dynamic-UDF upload and storage-plugin configuration are **admin-only, code/connectivity-execution-by-design** — i.e. a finding that requires those rights is out of model.
- **Q5.** Confirm operators with cluster-host / Drillbit-service-account / ZooKeeper-write access (and the data sources themselves) are out of model.

**Wave 2 — auth, impersonation, defaults**
Expand Down
Loading