diff options
Diffstat (limited to 'piolium/attack-surface/advisory-summary.md')
| -rw-r--r-- | piolium/attack-surface/advisory-summary.md | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/piolium/attack-surface/advisory-summary.md b/piolium/attack-surface/advisory-summary.md new file mode 100644 index 0000000..eaea57a --- /dev/null +++ b/piolium/attack-surface/advisory-summary.md | |||
| @@ -0,0 +1,395 @@ | |||
| 1 | # Advisory Summary: minecraft-ui | ||
| 2 | |||
| 3 | **Generated**: 2025-07-29T01:15:00Z | ||
| 4 | **Target**: `salmon/minecraft-ui` (self-hosted git at `git.2137697.xyz/salmon/minecraft-ui.git`) | ||
| 5 | **Analysis scope**: Stage 01 — Intelligence & Dependency Risk | ||
| 6 | |||
| 7 | --- | ||
| 8 | |||
| 9 | ## Repository Identity | ||
| 10 | |||
| 11 | | Field | Value | | ||
| 12 | |---|---| | ||
| 13 | | OWNER | `salmon` | | ||
| 14 | | REPO | `minecraft-ui` | | ||
| 15 | | OWNER_REPO | `salmon/minecraft-ui` | | ||
| 16 | | Resolution source | `git remote` (`https://git.2137697.xyz/salmon/minecraft-ui.git`) | | ||
| 17 | | Git history available | Yes (6 commits) | | ||
| 18 | | GitHub API available | No — self-hosted git server, not github.com | | ||
| 19 | | Primary ecosystem | Rust (Cargo) — edition 2024 | | ||
| 20 | | Total lines of code | ~3,213 (Rust source), 6 templates (Askama), 1 CSS, 1 JS (htmx) | | ||
| 21 | |||
| 22 | ## Coverage Gaps | ||
| 23 | |||
| 24 | - **Source 1 (git log CVE search)**: No CVE/GHSA references found in repo (0 results) — new project, no changelog, no SECURITY.md | ||
| 25 | - **Source 2 (GitHub Security Advisories)**: **Skipped** — `gh api` requires github.com; repo lives on `git.2137697.xyz` (self-hosted Gitea/Forgejo) | ||
| 26 | - **Source 5 (supplementary websearch)**: Not performed — Sources 1, 3, 4 cover all dependency advisories; no project-specific CVEs expected for a new internal tool | ||
| 27 | |||
| 28 | --- | ||
| 29 | |||
| 30 | ## Advisory Inventory | ||
| 31 | |||
| 32 | ### Direct Dependencies — Vulnerability Status | ||
| 33 | |||
| 34 | All 22 direct dependencies are at versions past all known advisories. No unfixed public vulnerabilities in the direct dependency tree. | ||
| 35 | |||
| 36 | | # | Package | Version | Known Advisories | Affected Range | Current Status | | ||
| 37 | |---|---------|---------|-----------------|---------------|----------------| | ||
| 38 | | 1 | `axum` | 0.8.9 | 0 | — | ✅ Clean | | ||
| 39 | | 2 | `multer` | 3.1.0 | 0 | — | ✅ Clean | | ||
| 40 | | 3 | `tokio` | 1.52.3 | 5 (historic) | All < 1.38.2 (oldest fix) | ✅ Fixed well above | | ||
| 41 | | 4 | `rusqlite` | 0.40.1 | 15 (historic) | < 0.25.4 (data races), < 0.26.2 (UAF) | ✅ Fixed well above | | ||
| 42 | | 5 | `bollard` | 0.17.1 | 2 | Checked — no active vulns | ✅ Clean | | ||
| 43 | | 6 | `argon2` | 0.5.3 | 0 | — | ✅ Clean | | ||
| 44 | | 7 | `zip` | 8.6.0 | **1 (CVE-2025-29787)** | 1.3.0 ≤ v < 2.3.0 | ✅ Fixed (v8.6.0 >> fix) | | ||
| 45 | | 8 | `reqwest` | 0.13.4 | 0 | — | ✅ Clean | | ||
| 46 | | 9 | `cookie` | 0.18.1 | 2 (historic) | < 0.7.6 | ✅ Fixed well above | | ||
| 47 | | 10 | `serde` | 1.0.228 | 0 | — | ✅ Clean | | ||
| 48 | | 11 | `askama` | 0.16.0 | 0 | — | ✅ Clean | | ||
| 49 | | 12 | `tower-http` | 0.7.0 (+ 0.6.11 transitive) | 2 (historic dir traversal) | < 0.1.3 / < 0.2.1 | ✅ Fixed well above | | ||
| 50 | | 13 | `axum-extra` | 0.12.6 | 0 | — | ✅ Clean | | ||
| 51 | | 14 | `tower` | 0.5.3 | 0 | — | ✅ Clean | | ||
| 52 | | 15 | `chrono` | 0.4.45 | 0 | — | ✅ Clean | | ||
| 53 | | 16 | `uuid` | 1.23.4 | 0 | — | ✅ Clean | | ||
| 54 | | 17 | `tempfile` | 3.27.0 | 3 | All historic/pre-2022 | ✅ Clean | | ||
| 55 | | 18 | `rand` | 0.8.7 | 1 (RUSTSEC-2026-0097) | 0.7.0 ≤ v < 0.8.6 | ✅ Fixed (0.8.7) | | ||
| 56 | | 19 | `tracing` | 0.1.44 | 1 (RUSTSEC-2023-0078 UAF) | 0.1.38 ≤ v < 0.1.40 | ✅ Fixed (0.1.44) | | ||
| 57 | | 20 | `serde_json` | 1.0.150 | 0 | — | ✅ Clean | | ||
| 58 | | 21 | `toml` | 1.1.2 | 0 | — | ✅ Clean | | ||
| 59 | | 22 | `futures-util` | 0.3.32 | 0 | — | ✅ Clean | | ||
| 60 | |||
| 61 | ### Notable Transitive Dependencies | ||
| 62 | |||
| 63 | | Package | Version | Known Advisories | Status | | ||
| 64 | |---------|---------|-----------------|--------| | ||
| 65 | | `hyper` | 1.10.1 | 0 | ✅ Clean | | ||
| 66 | | `h2` | 0.4.15 | 3 (all fixed in 0.4.4+) | ✅ Clean (0.4.15 > 0.4.4) | | ||
| 67 | | `mio` | 1.2.1 | 0 | ✅ Clean | | ||
| 68 | | `aes-gcm` | 0.10.3 | 0 | ✅ Clean | | ||
| 69 | |||
| 70 | ### Detailed Advisory Records | ||
| 71 | |||
| 72 | #### 1. CVE-2025-29787 — zip crate path traversal (HIGH) | ||
| 73 | |||
| 74 | | Field | Value | | ||
| 75 | |---|---| | ||
| 76 | | **ID** | `GHSA-94vh-gphv-8pm8` / `CVE-2025-29787` | | ||
| 77 | | **Published** | 2025-03-17 | | ||
| 78 | | **Severity** | HIGH (CVSS:4.0 8.1) | | ||
| 79 | | **Summary** | `zip` incorrectly canonicalizes paths during archive extraction, leading to arbitrary file write via path traversal | | ||
| 80 | | **CWEs** | CWE-180 (Incorrect Behavior Order), CWE-22 (Path Traversal), CWE-61 (UNIX Symbolic Link) | | ||
| 81 | | **Affected** | zip >= 1.3.0, < 2.3.0 | | ||
| 82 | | **Fixed in** | zip 2.3.0 | | ||
| 83 | | **Current** | 8.6.0 — **Not affected** | | ||
| 84 | | **Relevance** | The project uses `zip::ZipArchive` in `mods.rs` (mod extraction from ZIP), `routes/instances.rs` (world import), and `routes/backups.rs` (backup creation). All are using version 8.6.0, past the fix. | | ||
| 85 | |||
| 86 | #### 2. RUSTSEC-2025-0023 — tokio broadcast channel soundness | ||
| 87 | |||
| 88 | | Field | Value | | ||
| 89 | |---|---| | ||
| 90 | | **ID** | `GHSA-rr8g-9fpq-6wmg` | | ||
| 91 | | **Published** | 2025-04-07 | | ||
| 92 | | **Severity** | Informational (unsoundness) | | ||
| 93 | | **Summary** | `tokio::sync::broadcast` channel calls `clone` in parallel but does not require `Sync` | | ||
| 94 | | **Affected** | tokio >= 0.2.5 (various ranges) | | ||
| 95 | | **Fixed in** | 1.38.2 / 1.43.1 / 1.44.2 | | ||
| 96 | | **Current** | 1.52.3 — **Not affected** | | ||
| 97 | |||
| 98 | #### 3. RUSTSEC-2024-0332 — h2 CONTINUATION flood (HIGH) | ||
| 99 | |||
| 100 | | Field | Value | | ||
| 101 | |---|---| | ||
| 102 | | **ID** | `GHSA-q6cp-qfwq-4gcv` / `RUSTSEC-2024-0332` | | ||
| 103 | | **Published** | 2024-04-03 | | ||
| 104 | | **Severity** | HIGH | | ||
| 105 | | **Summary** | h2 servers vulnerable to degradation of service with CONTINUATION flood frames | | ||
| 106 | | **Affected** | h2 < 0.3.26 / < 0.4.4 | | ||
| 107 | | **Fixed in** | 0.4.4 | | ||
| 108 | | **Current** | 0.4.15 — **Not affected** | | ||
| 109 | |||
| 110 | #### 4. RUSTSEC-2023-0078 — tracing use-after-free | ||
| 111 | |||
| 112 | | Field | Value | | ||
| 113 | |---|---| | ||
| 114 | | **ID** | `GHSA-8f24-6m29-wm2r` | | ||
| 115 | | **Published** | 2024-01-17 | | ||
| 116 | | **Severity** | Informational | | ||
| 117 | | **Summary** | Use-after-free in tracing subscriber when `MakeVisitor` is implemented on a type that implements `Visit` without `Clone` | | ||
| 118 | | **Affected** | tracing >= 0.1.38, < 0.1.40 | | ||
| 119 | | **Fixed in** | 0.1.40 | | ||
| 120 | | **Current** | 0.1.44 — **Not affected** | | ||
| 121 | |||
| 122 | --- | ||
| 123 | |||
| 124 | ## Vulnerability Pattern Analysis | ||
| 125 | |||
| 126 | ### 2a. Component Vulnerability Heatmap | ||
| 127 | |||
| 128 | The project is a **brand-new codebase** with zero first-party CVEs. The heatmap below is derived from dependency advisory history and architectural analysis: | ||
| 129 | |||
| 130 | | Component | Advisory Count (historic) | Risk Factors | Dominant Bug Types | | ||
| 131 | |-----------|-------------------------|--------------|--------------------| | ||
| 132 | | **`rusqlite`** | 15 (all historic) | Data races (CVE-2020-35866..73), Use-After-Free (CVE-2021-45713..19) | Race conditions, UAF | | ||
| 133 | | **`tokio`** | 5 (all historic) | Race conditions, unsoundness | Concurrency bugs | | ||
| 134 | | **`h2`** (transitive) | 3 (all fixed by 0.4.4) | CONTINUATION flood, DoS | Resource exhaustion | | ||
| 135 | | **`zip`** | 1 (CVE-2025-29787, fixed in 2.3.0) | Path traversal, symlink | Path traversal | | ||
| 136 | | **`cookie`** | 2 (both historic, < 0.7.6) | Max-Age DoS, input validation | Input validation | | ||
| 137 | | **`tempfile`** | 3 (all historic) | Race conditions, permissions | TOCTOU | | ||
| 138 | | **`rand`** | 1 (RUSTSEC-2026-0097, fixed in 0.8.6) | Unsound with custom logger | Unsoundness | | ||
| 139 | |||
| 140 | **🔥 High-heat components requiring Phase 3/5 attention:** | ||
| 141 | 1. **`mods.rs` (480 lines)** — Custom JAR/ZIP parser, class-file constant pool scanning, ZIP extraction. Highest complexity, most attack surface. | ||
| 142 | 2. **`routes/instances.rs` (782 lines)** — World import/export (ZIP extraction), instance lifecycle, Docker orchestration. Largest single file. | ||
| 143 | 3. **`auth.rs` (199 lines)** — Session management, password hashing, cookie handling. Custom session cookie parsing (no library). | ||
| 144 | 4. **`docker.rs` (209 lines)** — Docker API calls with bollard, container creation with user-controlled env vars. | ||
| 145 | 5. **`rcon.rs` (127 lines)** — Raw TCP protocol implementation, password handling. | ||
| 146 | |||
| 147 | ### 2b. Bug Type Recurrence | ||
| 148 | |||
| 149 | | Bug Class | CWEs | Historic Count | Examples | Recurring? | | ||
| 150 | |-----------|------|---------------|----------|------------| | ||
| 151 | | **Race condition / TOCTOU** | CWE-362 | 8+ | rusqlite data races, tokio races, tempfile | ⚠️ **Recurring** | | ||
| 152 | | **Path traversal** | CWE-22 | 2 | zip (CVE-2025-29787), tower-http (RUSTSEC-2022-0043) | ⚠️ **Recurring** | | ||
| 153 | | **Resource exhaustion / DoS** | CWE-400, CWE-770 | 3 | h2 CONTINUATION flood, cookie Max-Age, h2 general | ⚠️ **Recurring** | | ||
| 154 | | **Use-after-free** | CWE-416 | 8 | rusqlite UAF, tracing UAF | ⚠️ **Recurring** | | ||
| 155 | | **Improper input validation** | CWE-20 | 2 | cookie, zip | — | | ||
| 156 | | **Unsoundness** | — | 2 | tokio broadcast, rand | — | | ||
| 157 | |||
| 158 | **Key insight**: Path traversal recurs across the dependency tree (zip and tower-http). The project's custom ZIP extraction code (`routes/instances.rs:import_world`) should be audited for the same pattern. | ||
| 159 | |||
| 160 | ### 2c. Attack Surface Trends | ||
| 161 | |||
| 162 | | Input Vector | Where Exploited | Risk Level | | ||
| 163 | |-------------|----------------|------------| | ||
| 164 | | **Uploaded ZIP/JAR files** | `routes/mods.rs`, `routes/instances.rs` (world import) | 🔴 **Critical** | | ||
| 165 | | **HTTP requests** (form data, multipart) | All routes via axum | 🟡 High | | ||
| 166 | | **Docker container env vars** | `docker.rs:recreate_container` — user-controlled (version, MOTD, etc.) | 🟡 High | | ||
| 167 | | **RCON network protocol** | `rcon.rs` — custom TCP implementation | 🟡 High | | ||
| 168 | | **SQL queries via rusqlite** | All DB operations (uses params! macro — safe) | 🟢 Low | | ||
| 169 | | **Cookie header parsing** | `auth.rs:require_auth` — manual cookie split | 🟡 Medium | | ||
| 170 | | **Template rendering** | Askama templates (compile-time, no injection) | 🟢 Low | | ||
| 171 | | **Config file** | `config.toml` parsed via toml crate | 🟢 Low | | ||
| 172 | |||
| 173 | **Highest-risk attack surface**: The mod upload/validation pipeline (`routes/mods.rs` + `mods.rs`) accepts arbitrary JAR/ZIP uploads with a 500MB size limit and performs custom bytecode-level class scanning. | ||
| 174 | |||
| 175 | ### 2d. Patch Quality Signals | ||
| 176 | |||
| 177 | No patch-bypass history exists for this project (new codebase, no patched vulnerabilities). However, several **architectural concerns** warrant attention: | ||
| 178 | |||
| 179 | 1. **`mods.rs` class-file scanner** — Custom constant pool parser (not using a library). Any bug in this parser could lead to mis-validation (accepting client-side mods that crash the server, or rejecting valid server mods). No fuzzing evidence exists. | ||
| 180 | |||
| 181 | 2. **`auth.rs` cookie session parsing** — Manual `split(';')` + `split_once('=')` parsing of the Cookie header. Equivalent to CWE-172 (Encoding Error). No library cookie parser used despite `cookie` crate being a dependency. | ||
| 182 | |||
| 183 | 3. **`docker.rs` env injection** — Instance name, MOTD, version, seed, etc. are directly interpolated into Docker container env vars. No sanitization of values that could contain shell-special characters or newlines (env var injection risk). | ||
| 184 | |||
| 185 | 4. **`rcon.rs` packet parsing** — Custom binary protocol parser with `i32::from_le_bytes` length prefix. Potential for integer underflow/overflow in length handling. | ||
| 186 | |||
| 187 | --- | ||
| 188 | |||
| 189 | ## Architecture Inventory | ||
| 190 | |||
| 191 | ### Components | ||
| 192 | |||
| 193 | | Component | File(s) | Purpose | Security Profile | | ||
| 194 | |-----------|---------|---------|-----------------| | ||
| 195 | | **HTTP Router** | `routes/mod.rs` | Axum router with auth middleware | Cookie-based session auth on protected routes | | ||
| 196 | | **Auth module** | `auth.rs` | Password hashing (Argon2), session creation, login/logout | Custom cookie parsing; sessions in SQLite | | ||
| 197 | | **Dashboard** | `routes/dashboard.rs` | Landing page showing active instance | Reads-only | | ||
| 198 | | **Instance Manager** | `routes/instances.rs` | CRUD for server instances, world import/export, activation | World ZIP import/extract; Docker lifecycle | | ||
| 199 | | **Mod Manager** | `routes/mods.rs`, `mods.rs` | JAR/ZIP upload, validation, class-file scanning | Largest attack surface: custom bytecode parser | | ||
| 200 | | **Player Manager** | `routes/players.rs` | RCON-based whitelist/OP/ban management | Sends commands via RCON to Minecraft server | | ||
| 201 | | **Backup Manager** | `routes/backups.rs` | Create/list/restore/download backups | ZIP creation, file read for download | | ||
| 202 | | **Account Manager** | `routes/accounts.rs` | Account CRUD, password change | Superuser-only; session invalidation on password change | | ||
| 203 | | **Docker Manager** | `docker.rs` | Container lifecycle via bollard API | Image pull, container create/start/stop with env vars | | ||
| 204 | | **RCON Client** | `rcon.rs` | Raw TCP RCON protocol implementation | Custom binary protocol parser | | ||
| 205 | | **Database** | `db.rs` | SQLite via rusqlite with connection pool (Arc<Mutex>) | WAL mode, foreign keys, migrations | | ||
| 206 | | **Config** | `config.rs` | TOML config loader | Static config, parsed at startup | | ||
| 207 | |||
| 208 | ### Transports | ||
| 209 | |||
| 210 | | Transport | Direction | Protocol | Used By | | ||
| 211 | |-----------|-----------|----------|---------| | ||
| 212 | | **HTTP** | User ↔ WebUI | HTTP/1.1 (via axum/hyper) | All routes | | ||
| 213 | | **Docker socket** | WebUI ↔ Docker daemon | Unix socket (bollard) | `docker.rs` | | ||
| 214 | | **RCON** | WebUI ↔ Minecraft server | TCP, custom binary protocol on port 25575 | `rcon.rs` | | ||
| 215 | | **Mojang API** | WebUI → piston-meta.mojang.com | HTTPS (reqwest) | Fetching version manifest | | ||
| 216 | | **File system** | WebUI ↔ Disk | Standard I/O | World export/import, mod uploads, backups | | ||
| 217 | |||
| 218 | ### Trust Boundaries | ||
| 219 | |||
| 220 | ``` | ||
| 221 | ┌─────────────────────────────────────────────────────────────────┐ | ||
| 222 | │ Internet / LAN │ | ||
| 223 | │ ┌────────────┐ HTTP :3000 ┌────────────────────────┐ │ | ||
| 224 | │ │ Browser │ ──────────────▶ │ WebUI (axum) │ │ | ||
| 225 | │ │ (HTMX/JS) │ │ minecraft-ui process │ │ | ||
| 226 | │ └────────────┘ │ - auth middleware │ │ | ||
| 227 | │ │ - cookie sessions │ │ | ||
| 228 | │ └──────┬─────────────────┘ │ | ||
| 229 | │ │ │ | ||
| 230 | │ ┌───────────────────────────────┼──────────────┐ │ | ||
| 231 | │ │ Docker daemon socket │ RCON TCP │ │ | ||
| 232 | │ ▼ ▼ │ │ | ||
| 233 | │ ┌─────────────────────┐ ┌───────────────────┐ │ │ | ||
| 234 | │ │ Docker Container │ │ Minecraft Server │ │ │ | ||
| 235 | │ │ itzg/minecraft-srv │ │ (inside Docker) │ │ │ | ||
| 236 | │ │ port 25565 │ │ port 25575 │ │ │ | ||
| 237 | │ │ port 25575 │ └───────────────────┘ │ │ | ||
| 238 | │ └─────────────────────┘ │ │ | ||
| 239 | │ │ │ | ||
| 240 | │ ┌────────────────────────────────────────────────────┐ │ │ | ||
| 241 | │ │ File System │ │ │ | ||
| 242 | │ │ - server_directory/instances/{name}/data/ │ │ │ | ||
| 243 | │ │ - server_directory/backups/ │ │ │ | ||
| 244 | │ │ - server_directory/mcui.db (SQLite) │ │ │ | ||
| 245 | │ └────────────────────────────────────────────────────┘ │ │ | ||
| 246 | └─────────────────────────────────────────────────────────────────┘ | ||
| 247 | ``` | ||
| 248 | |||
| 249 | ### Execution Environments | ||
| 250 | |||
| 251 | | Environment | Description | | ||
| 252 | |-------------|-------------| | ||
| 253 | | **Host OS** | Linux (presumed — Docker socket, Unix paths) | | ||
| 254 | | **Rust runtime** | Native binary via `tokio` async runtime | | ||
| 255 | | **Docker container** | `itzg/minecraft-server` with Java 8/17/21 depending on version | | ||
| 256 | | **SQLite** | Embedded database (WAL mode) | | ||
| 257 | |||
| 258 | ### Highest-Risk Flows (Phase 3 DFD priority) | ||
| 259 | |||
| 260 | 1. **Mod Upload → Validation → Disk Write** — External attacker-controlled JAR/ZIP → custom bytecode parser → file written to `mods/` directory | ||
| 261 | 2. **World Import → ZIP Extraction → Disk Write** — Uploaded ZIP → `zip::ZipArchive::by_index` → `enclosed_name()` → file extraction to `world/` | ||
| 262 | 3. **Instance Create → Docker Container Start** — User-controlled form fields → env var interpolation → Docker API call | ||
| 263 | 4. **Backup Download → File Read → HTTP Response** — Backup ID → file read from disk → streamed to user (path traversal risk) | ||
| 264 | 5. **Login → Cookie → Session** — Password verification → session creation → cookie parsing in auth middleware | ||
| 265 | |||
| 266 | --- | ||
| 267 | |||
| 268 | ## Component Inventory | ||
| 269 | |||
| 270 | ### Runtime | ||
| 271 | |||
| 272 | | Component | Version | Evidence | Security-relevant | | ||
| 273 | |-----------|---------|----------|-------------------| | ||
| 274 | | Rust | edition 2024 / stable | `Cargo.toml` | No | | ||
| 275 | |||
| 276 | ### Package Dependencies (direct) | ||
| 277 | |||
| 278 | | Component | Version | Purpose | Security-relevant | | ||
| 279 | |-----------|---------|---------|-------------------| | ||
| 280 | | axum | 0.8.9 | HTTP framework | Yes — request parsing | | ||
| 281 | | multer | 3.1.0 | Multipart uploads | Yes — file upload handling | | ||
| 282 | | tokio | 1.52.3 | Async runtime | Yes — concurrency | | ||
| 283 | | rusqlite | 0.40.1 | SQLite database | Yes — SQL injection surface | | ||
| 284 | | bollard | 0.17.1 | Docker API client | Yes — container control | | ||
| 285 | | argon2 | 0.5.3 | Password hashing | Yes — auth credential handling | | ||
| 286 | | zip | 8.6.0 | ZIP archive handling | Yes — file extraction | | ||
| 287 | | reqwest | 0.13.4 | HTTP client | No — version manifest fetches | | ||
| 288 | | cookie | 0.18.1 | Cookie handling | Yes — session cookies | | ||
| 289 | | serde | 1.0.228 | Serialization | No | | ||
| 290 | | askama | 0.16.0 | Template engine | No — compile-time templates | | ||
| 291 | | tower-http | 0.7.0 | HTTP middleware (static files) | No | | ||
| 292 | | axum-extra | 0.12.6 | Cookie private jar | Yes — session cookie crypto | | ||
| 293 | | chrono | 0.4.45 | Date/time | No | | ||
| 294 | | uuid | 1.23.4 | Session ID generation | No | | ||
| 295 | | tempfile | 3.27.0 | Temporary files | No | | ||
| 296 | | rand | 0.8.7 | RNG for passwords | Yes — RCON password generation | | ||
| 297 | | tracing | 0.1.44 | Logging | No | | ||
| 298 | | toml | 1.1.2 | Config parsing | No | | ||
| 299 | |||
| 300 | ### Binary Dependencies | ||
| 301 | |||
| 302 | | Component | Evidence | Purpose | Security-relevant | | ||
| 303 | |-----------|----------|---------|-------------------| | ||
| 304 | | Docker daemon | `bollard::Docker::connect_with_local_defaults()` | Container management | Yes — OS-level access | | ||
| 305 | | Java (JRE 8/17/21) | Docker `itzg/minecraft-server` images | Minecraft runtime | Yes — runs untrusted mod code | | ||
| 306 | | `itzg/minecraft-server` | Docker image | Minecraft server packaging | Yes — external image | | ||
| 307 | |||
| 308 | ### External Services | ||
| 309 | |||
| 310 | | Service | Evidence | Purpose | Security-relevant | | ||
| 311 | |---------|----------|---------|-------------------| | ||
| 312 | | `piston-meta.mojang.com` | `reqwest::get(...)` in `fetch_minecraft_versions()` | Version manifest | No — read-only public API | | ||
| 313 | |||
| 314 | ### Datastores | ||
| 315 | |||
| 316 | | Component | Evidence | Purpose | Security-relevant | | ||
| 317 | |-----------|----------|---------|-------------------| | ||
| 318 | | SQLite (rusqlite) | `db.rs` | Accounts, sessions, instances, mods | Yes — credential storage | | ||
| 319 | | Docker volume mounts | `docker.rs` | Minecraft server data | Yes — file system access | | ||
| 320 | | Server directory | `config.toml:server_directory` | All persistent data | Yes — file system root | | ||
| 321 | |||
| 322 | ### Coverage Gaps | ||
| 323 | |||
| 324 | | Category | Status | Note | | ||
| 325 | |----------|--------|------| | ||
| 326 | | runtime | ✅ Covered | Rust edition 2024 | | ||
| 327 | | package | ✅ Covered | All 22 direct deps from Cargo.toml | | ||
| 328 | | framework | ✅ Covered | axum, askama | | ||
| 329 | | datastore | ✅ Covered | SQLite, Docker volumes | | ||
| 330 | | external-service | ✅ Covered | Mojang API | | ||
| 331 | | container-os | ⚠️ Partial | Dockerfile not in repo; uses `itzg/minecraft-server` images | | ||
| 332 | | build-ci | ℹ️ None detected | No CI config found in repo | | ||
| 333 | | binary | ✅ Covered | Docker, Java (via Docker) | | ||
| 334 | | vendored | ✅ Covered | `static/htmx.min.js` (vendored JS library) | | ||
| 335 | |||
| 336 | --- | ||
| 337 | |||
| 338 | ## Dependency Intelligence | ||
| 339 | |||
| 340 | ### Security-Relevant Dependencies (derived view) | ||
| 341 | |||
| 342 | | Dependency | Version | Risk Factors | Pattern Cross-Reference | | ||
| 343 | |-----------|---------|-------------|------------------------| | ||
| 344 | | **axum** | 0.8.9 | Input parsing, multipart handling | HTTP request surface (2c) | | ||
| 345 | | **multer** | 3.1.0 | Multipart file upload with 500MB limit | File upload attack surface (2c) | | ||
| 346 | | **rusqlite** | 0.40.1 | →historic: data races, UAF | Bug class: race conditions (2b) | | ||
| 347 | | **bollard** | 0.17.1 | Docker socket access, container control | Docker API attack surface (2c) | | ||
| 348 | | **argon2** | 0.5.3 | Password hashing — credential protection | Auth security (2c) | | ||
| 349 | | **zip** | 8.6.0 | →historic: path traversal (CVE-2025-29787) | Bug class: path traversal (2b) | | ||
| 350 | | **cookie** | 0.18.1 | →historic: DoS via Max-Age | Session handling (2c) | | ||
| 351 | | **axum-extra** | 0.12.6 | Cookie private jar (encryption) | Session security | | ||
| 352 | | **rand** | 0.8.7 | RCON password generation | Password strength | | ||
| 353 | |||
| 354 | ### Key Risk Observations | ||
| 355 | |||
| 356 | 1. **No regular dependency scanning configured** — No `cargo audit` or `cargo deny` in CI. Relying on manual version choice. | ||
| 357 | 2. **`htmx.min.js` (vendored)** — Static file served via `tower-http::services::ServeDir`. Should verify integrity of vendored copy. | ||
| 358 | 3. **`itzg/minecraft-server` Docker images** — External base images with Java runtimes. Image pull happens at runtime; no image hash pinning in code. | ||
| 359 | 4. **RCON password generation** — Uses `rand::thread_rng()` (CSPRNG) with 16-char alphanumeric charset (~93 bits entropy). Adequate but no periodic rotation. | ||
| 360 | |||
| 361 | --- | ||
| 362 | |||
| 363 | ## Audit Targeting Recommendations | ||
| 364 | |||
| 365 | Based on pattern analysis: | ||
| 366 | |||
| 367 | 1. **Phase 3 DFD priorities**: | ||
| 368 | - **Mod upload/validation pipeline** (`routes/mods.rs` + `mods.rs`) — highest complexity, custom bytecode parser | ||
| 369 | - **World import/export** (`routes/instances.rs:import_world`, `export_world`) — ZIP extraction to disk | ||
| 370 | - **Auth middleware** (`auth.rs:require_auth`) — custom cookie parsing without library | ||
| 371 | |||
| 372 | 2. **Phase 5 deep probe targets**: | ||
| 373 | - **Mod validation bypass** — Can a crafted JAR bypass the class-file scanner? (CWE-22, CWE-180) | ||
| 374 | - **Path traversal in world ZIP extraction** — `zip::ZipArchive::by_index().enclosed_name()` usage | ||
| 375 | - **Docker env var injection** — User-controlled values in container creation | ||
| 376 | - **RCON protocol weaknesses** — Integer handling in packet length parsing | ||
| 377 | |||
| 378 | 3. **Phase 10 chambers (mandatory attack modes)**: | ||
| 379 | - Path traversal (CWE-22) | ||
| 380 | - Injection (command/env/XML via Docker env) | ||
| 381 | - Deserialization (JAR/ZIP parsing) | ||
| 382 | - Race conditions (SQLite, file operations) | ||
| 383 | - Auth bypass (cookie forging) | ||
| 384 | |||
| 385 | 4. **Patch-bypass-checker candidates**: | ||
| 386 | - No structural-recurrence candidates (new codebase) — but the ZIP extraction code in both `routes/instances.rs` and `routes/backups.rs` should be compared for consistency | ||
| 387 | |||
| 388 | --- | ||
| 389 | |||
| 390 | ## References | ||
| 391 | |||
| 392 | - OSV.dev queries: 22 direct deps + 5 transitive checked | ||
| 393 | - NVD keywordSearch for "minecraft-ui": 0 results | ||
| 394 | - Git log: 6 commits, no CVE references | ||
| 395 | - Source analysis: 3,213 lines across 16 Rust files | ||
