# Advisory Summary: minecraft-ui **Generated**: 2025-07-29T01:15:00Z **Target**: `salmon/minecraft-ui` (self-hosted git at `git.2137697.xyz/salmon/minecraft-ui.git`) **Analysis scope**: Stage 01 — Intelligence & Dependency Risk --- ## Repository Identity | Field | Value | |---|---| | OWNER | `salmon` | | REPO | `minecraft-ui` | | OWNER_REPO | `salmon/minecraft-ui` | | Resolution source | `git remote` (`https://git.2137697.xyz/salmon/minecraft-ui.git`) | | Git history available | Yes (6 commits) | | GitHub API available | No — self-hosted git server, not github.com | | Primary ecosystem | Rust (Cargo) — edition 2024 | | Total lines of code | ~3,213 (Rust source), 6 templates (Askama), 1 CSS, 1 JS (htmx) | ## Coverage Gaps - **Source 1 (git log CVE search)**: No CVE/GHSA references found in repo (0 results) — new project, no changelog, no SECURITY.md - **Source 2 (GitHub Security Advisories)**: **Skipped** — `gh api` requires github.com; repo lives on `git.2137697.xyz` (self-hosted Gitea/Forgejo) - **Source 5 (supplementary websearch)**: Not performed — Sources 1, 3, 4 cover all dependency advisories; no project-specific CVEs expected for a new internal tool --- ## Advisory Inventory ### Direct Dependencies — Vulnerability Status All 22 direct dependencies are at versions past all known advisories. No unfixed public vulnerabilities in the direct dependency tree. | # | Package | Version | Known Advisories | Affected Range | Current Status | |---|---------|---------|-----------------|---------------|----------------| | 1 | `axum` | 0.8.9 | 0 | — | ✅ Clean | | 2 | `multer` | 3.1.0 | 0 | — | ✅ Clean | | 3 | `tokio` | 1.52.3 | 5 (historic) | All < 1.38.2 (oldest fix) | ✅ Fixed well above | | 4 | `rusqlite` | 0.40.1 | 15 (historic) | < 0.25.4 (data races), < 0.26.2 (UAF) | ✅ Fixed well above | | 5 | `bollard` | 0.17.1 | 2 | Checked — no active vulns | ✅ Clean | | 6 | `argon2` | 0.5.3 | 0 | — | ✅ Clean | | 7 | `zip` | 8.6.0 | **1 (CVE-2025-29787)** | 1.3.0 ≤ v < 2.3.0 | ✅ Fixed (v8.6.0 >> fix) | | 8 | `reqwest` | 0.13.4 | 0 | — | ✅ Clean | | 9 | `cookie` | 0.18.1 | 2 (historic) | < 0.7.6 | ✅ Fixed well above | | 10 | `serde` | 1.0.228 | 0 | — | ✅ Clean | | 11 | `askama` | 0.16.0 | 0 | — | ✅ Clean | | 12 | `tower-http` | 0.7.0 (+ 0.6.11 transitive) | 2 (historic dir traversal) | < 0.1.3 / < 0.2.1 | ✅ Fixed well above | | 13 | `axum-extra` | 0.12.6 | 0 | — | ✅ Clean | | 14 | `tower` | 0.5.3 | 0 | — | ✅ Clean | | 15 | `chrono` | 0.4.45 | 0 | — | ✅ Clean | | 16 | `uuid` | 1.23.4 | 0 | — | ✅ Clean | | 17 | `tempfile` | 3.27.0 | 3 | All historic/pre-2022 | ✅ Clean | | 18 | `rand` | 0.8.7 | 1 (RUSTSEC-2026-0097) | 0.7.0 ≤ v < 0.8.6 | ✅ Fixed (0.8.7) | | 19 | `tracing` | 0.1.44 | 1 (RUSTSEC-2023-0078 UAF) | 0.1.38 ≤ v < 0.1.40 | ✅ Fixed (0.1.44) | | 20 | `serde_json` | 1.0.150 | 0 | — | ✅ Clean | | 21 | `toml` | 1.1.2 | 0 | — | ✅ Clean | | 22 | `futures-util` | 0.3.32 | 0 | — | ✅ Clean | ### Notable Transitive Dependencies | Package | Version | Known Advisories | Status | |---------|---------|-----------------|--------| | `hyper` | 1.10.1 | 0 | ✅ Clean | | `h2` | 0.4.15 | 3 (all fixed in 0.4.4+) | ✅ Clean (0.4.15 > 0.4.4) | | `mio` | 1.2.1 | 0 | ✅ Clean | | `aes-gcm` | 0.10.3 | 0 | ✅ Clean | ### Detailed Advisory Records #### 1. CVE-2025-29787 — zip crate path traversal (HIGH) | Field | Value | |---|---| | **ID** | `GHSA-94vh-gphv-8pm8` / `CVE-2025-29787` | | **Published** | 2025-03-17 | | **Severity** | HIGH (CVSS:4.0 8.1) | | **Summary** | `zip` incorrectly canonicalizes paths during archive extraction, leading to arbitrary file write via path traversal | | **CWEs** | CWE-180 (Incorrect Behavior Order), CWE-22 (Path Traversal), CWE-61 (UNIX Symbolic Link) | | **Affected** | zip >= 1.3.0, < 2.3.0 | | **Fixed in** | zip 2.3.0 | | **Current** | 8.6.0 — **Not affected** | | **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. | #### 2. RUSTSEC-2025-0023 — tokio broadcast channel soundness | Field | Value | |---|---| | **ID** | `GHSA-rr8g-9fpq-6wmg` | | **Published** | 2025-04-07 | | **Severity** | Informational (unsoundness) | | **Summary** | `tokio::sync::broadcast` channel calls `clone` in parallel but does not require `Sync` | | **Affected** | tokio >= 0.2.5 (various ranges) | | **Fixed in** | 1.38.2 / 1.43.1 / 1.44.2 | | **Current** | 1.52.3 — **Not affected** | #### 3. RUSTSEC-2024-0332 — h2 CONTINUATION flood (HIGH) | Field | Value | |---|---| | **ID** | `GHSA-q6cp-qfwq-4gcv` / `RUSTSEC-2024-0332` | | **Published** | 2024-04-03 | | **Severity** | HIGH | | **Summary** | h2 servers vulnerable to degradation of service with CONTINUATION flood frames | | **Affected** | h2 < 0.3.26 / < 0.4.4 | | **Fixed in** | 0.4.4 | | **Current** | 0.4.15 — **Not affected** | #### 4. RUSTSEC-2023-0078 — tracing use-after-free | Field | Value | |---|---| | **ID** | `GHSA-8f24-6m29-wm2r` | | **Published** | 2024-01-17 | | **Severity** | Informational | | **Summary** | Use-after-free in tracing subscriber when `MakeVisitor` is implemented on a type that implements `Visit` without `Clone` | | **Affected** | tracing >= 0.1.38, < 0.1.40 | | **Fixed in** | 0.1.40 | | **Current** | 0.1.44 — **Not affected** | --- ## Vulnerability Pattern Analysis ### 2a. Component Vulnerability Heatmap The project is a **brand-new codebase** with zero first-party CVEs. The heatmap below is derived from dependency advisory history and architectural analysis: | Component | Advisory Count (historic) | Risk Factors | Dominant Bug Types | |-----------|-------------------------|--------------|--------------------| | **`rusqlite`** | 15 (all historic) | Data races (CVE-2020-35866..73), Use-After-Free (CVE-2021-45713..19) | Race conditions, UAF | | **`tokio`** | 5 (all historic) | Race conditions, unsoundness | Concurrency bugs | | **`h2`** (transitive) | 3 (all fixed by 0.4.4) | CONTINUATION flood, DoS | Resource exhaustion | | **`zip`** | 1 (CVE-2025-29787, fixed in 2.3.0) | Path traversal, symlink | Path traversal | | **`cookie`** | 2 (both historic, < 0.7.6) | Max-Age DoS, input validation | Input validation | | **`tempfile`** | 3 (all historic) | Race conditions, permissions | TOCTOU | | **`rand`** | 1 (RUSTSEC-2026-0097, fixed in 0.8.6) | Unsound with custom logger | Unsoundness | **🔥 High-heat components requiring Phase 3/5 attention:** 1. **`mods.rs` (480 lines)** — Custom JAR/ZIP parser, class-file constant pool scanning, ZIP extraction. Highest complexity, most attack surface. 2. **`routes/instances.rs` (782 lines)** — World import/export (ZIP extraction), instance lifecycle, Docker orchestration. Largest single file. 3. **`auth.rs` (199 lines)** — Session management, password hashing, cookie handling. Custom session cookie parsing (no library). 4. **`docker.rs` (209 lines)** — Docker API calls with bollard, container creation with user-controlled env vars. 5. **`rcon.rs` (127 lines)** — Raw TCP protocol implementation, password handling. ### 2b. Bug Type Recurrence | Bug Class | CWEs | Historic Count | Examples | Recurring? | |-----------|------|---------------|----------|------------| | **Race condition / TOCTOU** | CWE-362 | 8+ | rusqlite data races, tokio races, tempfile | ⚠️ **Recurring** | | **Path traversal** | CWE-22 | 2 | zip (CVE-2025-29787), tower-http (RUSTSEC-2022-0043) | ⚠️ **Recurring** | | **Resource exhaustion / DoS** | CWE-400, CWE-770 | 3 | h2 CONTINUATION flood, cookie Max-Age, h2 general | ⚠️ **Recurring** | | **Use-after-free** | CWE-416 | 8 | rusqlite UAF, tracing UAF | ⚠️ **Recurring** | | **Improper input validation** | CWE-20 | 2 | cookie, zip | — | | **Unsoundness** | — | 2 | tokio broadcast, rand | — | **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. ### 2c. Attack Surface Trends | Input Vector | Where Exploited | Risk Level | |-------------|----------------|------------| | **Uploaded ZIP/JAR files** | `routes/mods.rs`, `routes/instances.rs` (world import) | 🔴 **Critical** | | **HTTP requests** (form data, multipart) | All routes via axum | 🟡 High | | **Docker container env vars** | `docker.rs:recreate_container` — user-controlled (version, MOTD, etc.) | 🟡 High | | **RCON network protocol** | `rcon.rs` — custom TCP implementation | 🟡 High | | **SQL queries via rusqlite** | All DB operations (uses params! macro — safe) | 🟢 Low | | **Cookie header parsing** | `auth.rs:require_auth` — manual cookie split | 🟡 Medium | | **Template rendering** | Askama templates (compile-time, no injection) | 🟢 Low | | **Config file** | `config.toml` parsed via toml crate | 🟢 Low | **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. ### 2d. Patch Quality Signals No patch-bypass history exists for this project (new codebase, no patched vulnerabilities). However, several **architectural concerns** warrant attention: 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. 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. 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). 4. **`rcon.rs` packet parsing** — Custom binary protocol parser with `i32::from_le_bytes` length prefix. Potential for integer underflow/overflow in length handling. --- ## Architecture Inventory ### Components | Component | File(s) | Purpose | Security Profile | |-----------|---------|---------|-----------------| | **HTTP Router** | `routes/mod.rs` | Axum router with auth middleware | Cookie-based session auth on protected routes | | **Auth module** | `auth.rs` | Password hashing (Argon2), session creation, login/logout | Custom cookie parsing; sessions in SQLite | | **Dashboard** | `routes/dashboard.rs` | Landing page showing active instance | Reads-only | | **Instance Manager** | `routes/instances.rs` | CRUD for server instances, world import/export, activation | World ZIP import/extract; Docker lifecycle | | **Mod Manager** | `routes/mods.rs`, `mods.rs` | JAR/ZIP upload, validation, class-file scanning | Largest attack surface: custom bytecode parser | | **Player Manager** | `routes/players.rs` | RCON-based whitelist/OP/ban management | Sends commands via RCON to Minecraft server | | **Backup Manager** | `routes/backups.rs` | Create/list/restore/download backups | ZIP creation, file read for download | | **Account Manager** | `routes/accounts.rs` | Account CRUD, password change | Superuser-only; session invalidation on password change | | **Docker Manager** | `docker.rs` | Container lifecycle via bollard API | Image pull, container create/start/stop with env vars | | **RCON Client** | `rcon.rs` | Raw TCP RCON protocol implementation | Custom binary protocol parser | | **Database** | `db.rs` | SQLite via rusqlite with connection pool (Arc) | WAL mode, foreign keys, migrations | | **Config** | `config.rs` | TOML config loader | Static config, parsed at startup | ### Transports | Transport | Direction | Protocol | Used By | |-----------|-----------|----------|---------| | **HTTP** | User ↔ WebUI | HTTP/1.1 (via axum/hyper) | All routes | | **Docker socket** | WebUI ↔ Docker daemon | Unix socket (bollard) | `docker.rs` | | **RCON** | WebUI ↔ Minecraft server | TCP, custom binary protocol on port 25575 | `rcon.rs` | | **Mojang API** | WebUI → piston-meta.mojang.com | HTTPS (reqwest) | Fetching version manifest | | **File system** | WebUI ↔ Disk | Standard I/O | World export/import, mod uploads, backups | ### Trust Boundaries ``` ┌─────────────────────────────────────────────────────────────────┐ │ Internet / LAN │ │ ┌────────────┐ HTTP :3000 ┌────────────────────────┐ │ │ │ Browser │ ──────────────▶ │ WebUI (axum) │ │ │ │ (HTMX/JS) │ │ minecraft-ui process │ │ │ └────────────┘ │ - auth middleware │ │ │ │ - cookie sessions │ │ │ └──────┬─────────────────┘ │ │ │ │ │ ┌───────────────────────────────┼──────────────┐ │ │ │ Docker daemon socket │ RCON TCP │ │ │ ▼ ▼ │ │ │ ┌─────────────────────┐ ┌───────────────────┐ │ │ │ │ Docker Container │ │ Minecraft Server │ │ │ │ │ itzg/minecraft-srv │ │ (inside Docker) │ │ │ │ │ port 25565 │ │ port 25575 │ │ │ │ │ port 25575 │ └───────────────────┘ │ │ │ └─────────────────────┘ │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ File System │ │ │ │ │ - server_directory/instances/{name}/data/ │ │ │ │ │ - server_directory/backups/ │ │ │ │ │ - server_directory/mcui.db (SQLite) │ │ │ │ └────────────────────────────────────────────────────┘ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### Execution Environments | Environment | Description | |-------------|-------------| | **Host OS** | Linux (presumed — Docker socket, Unix paths) | | **Rust runtime** | Native binary via `tokio` async runtime | | **Docker container** | `itzg/minecraft-server` with Java 8/17/21 depending on version | | **SQLite** | Embedded database (WAL mode) | ### Highest-Risk Flows (Phase 3 DFD priority) 1. **Mod Upload → Validation → Disk Write** — External attacker-controlled JAR/ZIP → custom bytecode parser → file written to `mods/` directory 2. **World Import → ZIP Extraction → Disk Write** — Uploaded ZIP → `zip::ZipArchive::by_index` → `enclosed_name()` → file extraction to `world/` 3. **Instance Create → Docker Container Start** — User-controlled form fields → env var interpolation → Docker API call 4. **Backup Download → File Read → HTTP Response** — Backup ID → file read from disk → streamed to user (path traversal risk) 5. **Login → Cookie → Session** — Password verification → session creation → cookie parsing in auth middleware --- ## Component Inventory ### Runtime | Component | Version | Evidence | Security-relevant | |-----------|---------|----------|-------------------| | Rust | edition 2024 / stable | `Cargo.toml` | No | ### Package Dependencies (direct) | Component | Version | Purpose | Security-relevant | |-----------|---------|---------|-------------------| | axum | 0.8.9 | HTTP framework | Yes — request parsing | | multer | 3.1.0 | Multipart uploads | Yes — file upload handling | | tokio | 1.52.3 | Async runtime | Yes — concurrency | | rusqlite | 0.40.1 | SQLite database | Yes — SQL injection surface | | bollard | 0.17.1 | Docker API client | Yes — container control | | argon2 | 0.5.3 | Password hashing | Yes — auth credential handling | | zip | 8.6.0 | ZIP archive handling | Yes — file extraction | | reqwest | 0.13.4 | HTTP client | No — version manifest fetches | | cookie | 0.18.1 | Cookie handling | Yes — session cookies | | serde | 1.0.228 | Serialization | No | | askama | 0.16.0 | Template engine | No — compile-time templates | | tower-http | 0.7.0 | HTTP middleware (static files) | No | | axum-extra | 0.12.6 | Cookie private jar | Yes — session cookie crypto | | chrono | 0.4.45 | Date/time | No | | uuid | 1.23.4 | Session ID generation | No | | tempfile | 3.27.0 | Temporary files | No | | rand | 0.8.7 | RNG for passwords | Yes — RCON password generation | | tracing | 0.1.44 | Logging | No | | toml | 1.1.2 | Config parsing | No | ### Binary Dependencies | Component | Evidence | Purpose | Security-relevant | |-----------|----------|---------|-------------------| | Docker daemon | `bollard::Docker::connect_with_local_defaults()` | Container management | Yes — OS-level access | | Java (JRE 8/17/21) | Docker `itzg/minecraft-server` images | Minecraft runtime | Yes — runs untrusted mod code | | `itzg/minecraft-server` | Docker image | Minecraft server packaging | Yes — external image | ### External Services | Service | Evidence | Purpose | Security-relevant | |---------|----------|---------|-------------------| | `piston-meta.mojang.com` | `reqwest::get(...)` in `fetch_minecraft_versions()` | Version manifest | No — read-only public API | ### Datastores | Component | Evidence | Purpose | Security-relevant | |-----------|----------|---------|-------------------| | SQLite (rusqlite) | `db.rs` | Accounts, sessions, instances, mods | Yes — credential storage | | Docker volume mounts | `docker.rs` | Minecraft server data | Yes — file system access | | Server directory | `config.toml:server_directory` | All persistent data | Yes — file system root | ### Coverage Gaps | Category | Status | Note | |----------|--------|------| | runtime | ✅ Covered | Rust edition 2024 | | package | ✅ Covered | All 22 direct deps from Cargo.toml | | framework | ✅ Covered | axum, askama | | datastore | ✅ Covered | SQLite, Docker volumes | | external-service | ✅ Covered | Mojang API | | container-os | ⚠️ Partial | Dockerfile not in repo; uses `itzg/minecraft-server` images | | build-ci | ℹ️ None detected | No CI config found in repo | | binary | ✅ Covered | Docker, Java (via Docker) | | vendored | ✅ Covered | `static/htmx.min.js` (vendored JS library) | --- ## Dependency Intelligence ### Security-Relevant Dependencies (derived view) | Dependency | Version | Risk Factors | Pattern Cross-Reference | |-----------|---------|-------------|------------------------| | **axum** | 0.8.9 | Input parsing, multipart handling | HTTP request surface (2c) | | **multer** | 3.1.0 | Multipart file upload with 500MB limit | File upload attack surface (2c) | | **rusqlite** | 0.40.1 | →historic: data races, UAF | Bug class: race conditions (2b) | | **bollard** | 0.17.1 | Docker socket access, container control | Docker API attack surface (2c) | | **argon2** | 0.5.3 | Password hashing — credential protection | Auth security (2c) | | **zip** | 8.6.0 | →historic: path traversal (CVE-2025-29787) | Bug class: path traversal (2b) | | **cookie** | 0.18.1 | →historic: DoS via Max-Age | Session handling (2c) | | **axum-extra** | 0.12.6 | Cookie private jar (encryption) | Session security | | **rand** | 0.8.7 | RCON password generation | Password strength | ### Key Risk Observations 1. **No regular dependency scanning configured** — No `cargo audit` or `cargo deny` in CI. Relying on manual version choice. 2. **`htmx.min.js` (vendored)** — Static file served via `tower-http::services::ServeDir`. Should verify integrity of vendored copy. 3. **`itzg/minecraft-server` Docker images** — External base images with Java runtimes. Image pull happens at runtime; no image hash pinning in code. 4. **RCON password generation** — Uses `rand::thread_rng()` (CSPRNG) with 16-char alphanumeric charset (~93 bits entropy). Adequate but no periodic rotation. --- ## Audit Targeting Recommendations Based on pattern analysis: 1. **Phase 3 DFD priorities**: - **Mod upload/validation pipeline** (`routes/mods.rs` + `mods.rs`) — highest complexity, custom bytecode parser - **World import/export** (`routes/instances.rs:import_world`, `export_world`) — ZIP extraction to disk - **Auth middleware** (`auth.rs:require_auth`) — custom cookie parsing without library 2. **Phase 5 deep probe targets**: - **Mod validation bypass** — Can a crafted JAR bypass the class-file scanner? (CWE-22, CWE-180) - **Path traversal in world ZIP extraction** — `zip::ZipArchive::by_index().enclosed_name()` usage - **Docker env var injection** — User-controlled values in container creation - **RCON protocol weaknesses** — Integer handling in packet length parsing 3. **Phase 10 chambers (mandatory attack modes)**: - Path traversal (CWE-22) - Injection (command/env/XML via Docker env) - Deserialization (JAR/ZIP parsing) - Race conditions (SQLite, file operations) - Auth bypass (cookie forging) 4. **Patch-bypass-checker candidates**: - 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 --- ## References - OSV.dev queries: 22 direct deps + 5 transitive checked - NVD keywordSearch for "minecraft-ui": 0 results - Git log: 6 commits, no CVE references - Source analysis: 3,213 lines across 16 Rust files