1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
# Security Audit Report: salmon/minecraft-ui
=========================================
## Executive Summary
This audit of **minecraft-ui** — a self-hosted Rust (axum) web application that manages Docker-based Minecraft server instances — identified **17 validated vulnerabilities** spanning path traversal, injection, CSRF, session management, authorization, concurrency, denial-of-service, and cryptographic weaknesses. The most critical issue is **arbitrary filesystem access via unsanitized instance names** (AP-001), which enables path-traversal-driven directory creation, deletion, and constrained file read/write across 12 confirmed code paths — including 4 variant instances discovered in Phase 12. Four high-severity findings were cold-verified via adversarial review (P11). Combined with universal CSRF absence (31 POST endpoints) and a flat authorization model, the application provides minimal defense-in-depth: any authenticated user can destroy data, modify server configurations, or gain persistent access to Minecraft server consoles. The audit reached draft stage but the **findings promotion pipeline stalled** — no PoCs were built and no `piolium/findings/` directory was created. This report is assembled from available draft, chamber, and knowledge-base artifacts.
## Methodology Summary
- **Intelligence Gathering:** Advisory collection via `cargo-audit-advisory` (SBOM), architecture inventory of 16 Rust source files, dependency analysis (rusqlite, bollard, multer, zip)
- **Knowledge Base:** Threat modeling with DFD/CFD slices (P3), manual attack surface inventory of 38 routes (P8), domain attack research (Minecraft RCON, Java .properties, Docker env injection)
- **Static Analysis:** Structural extraction via manual code review; CodeQL database could not be built (system constraint); Semgrep ran but with limited Rust rule coverage
- **Review Chambers:** 6-cluster multi-agent debate system (path-traversal, injection, auth-session, state-concurrency, denial-of-service, security-architecture). 37 findings from P4/P5/P6/P8 reviewed → **17 VALID** survivors, 7 FALSE POSITIVE, 8 DROP, 5 DUPLICATE
- **Verification:** P11 cold verification (adversarial review) for 4 highest-severity findings: p10-001 (CONFIRMED), p10-003 (CONFIRMED), p10-004 (DISPROVED), p10-005 (CONFIRMED with severity downgrade challenge)
- **Variant Analysis (P12):** 4 path-traversal variants discovered from AP-001 root cause search
## Summary of Findings
| ID | Title | Severity | PoC Status | Status |
|----|-------|----------|------------|--------|
| — | Instance Name Path Traversal (p10-001) | CRITICAL | draft-only | Not promoted |
| — | Level-Seed Properties Injection (p10-003) | HIGH | draft-only | Not promoted |
| — | Missing CSRF Protection (p10-005) | HIGH | draft-only | Not promoted |
| — | RCON Password Exposed to All Users (p10-004) | **LOW** (DISPROVED) | blocked | Adversarial reversal |
| — | RCON Command Injection (p10-002) | MEDIUM | draft-only | Not promoted |
| — | Flat Authorization Model (p10-010) | MEDIUM | draft-only | Not promoted |
| — | No Server-Side Session TTL (p10-006) | MEDIUM | draft-only | Not promoted |
| — | No Rate Limiting Login (p10-007) | MEDIUM | draft-only | Not promoted |
| — | Background Task Stale is_active (p10-011) | MEDIUM | draft-only | Not promoted |
| — | Delete-Create Name Reuse Race (p10-012) | MEDIUM | draft-only | Not promoted |
| — | No Idempotency (p10-013) | MEDIUM | draft-only | Not promoted |
| — | Mod Validation Denial of Service (p10-016) | MEDIUM | draft-only | Not promoted |
| — | No Encryption at Rest (p10-017) | MEDIUM | draft-only | Not promoted |
| — | Logout No Auth Middleware (p10-008) | LOW | draft-only | Not promoted |
| — | Cookie No Secure Flag (p10-009) | LOW | draft-only | Not promoted |
| — | Mod Write Before DB Orphan (p10-014) | LOW | draft-only | Not promoted |
| — | Backup Orphan Race (p10-015) | LOW | draft-only | Not promoted |
### Variant Findings (Phase 12)
| Variant ID | Title | Severity | Parent | PoC Status |
|-----------|-------|----------|--------|------------|
| p12-001 | World Import Path Traversal | HIGH | p10-001 | draft-only |
| p12-002 | Regenerate World Path Traversal | HIGH | p10-001 | draft-only |
| p12-003 | Player Management Path Traversal | MEDIUM | p10-001 | draft-only |
| p12-004 | Backup Create Path Traversal | MEDIUM | p10-001 | draft-only |
> **Note:** No findings were promoted to `piolium/findings/` with PoC scripts, evidence, or full report.md files. All entries above remain at draft stage in `piolium/findings-draft/`.
---
## Technical Findings Detail
### Instance Name Path Traversal (p10-001 — CRITICAL equivalent)
- **Severity:** CRITICAL
- **Summary:** The instance `name` field flows unsanitized into `Path::join()` for 8 different filesystem operations. Rust's `Path::join()` follows `..` components, enabling arbitrary directory creation, deletion, and constrained file read/write outside the intended data directory.
- **Impact:** An authenticated attacker can:
- **Delete arbitrary directories** via `remove_dir_all` (path: `src/routes/instances.rs:388-392`) — e.g., name=`../../../target` deletes the project build directory
- **Create arbitrary directories** via `create_dir_all` (path: `src/routes/instances.rs:204-206`)
- **Write files to arbitrary locations** (constrained by `/mods/` or `/data/world/` suffix chaining via mod upload and world import)
- **Read files from arbitrary locations** (constrained by world export and backup download paths)
- **Root Cause:** `Path::join()` in Rust follows `..` components. User-controlled `form.name` is passed directly with no sanitization, length limits, or character restrictions. No validation exists at any of the 12 known join call sites.
- **Key Code Reference:** `src/routes/instances.rs:204-206` — `Path::join(&form.name)` → `create_dir_all`
- **PoC Status:** draft-only (no executable PoC built)
- **Detailed Report:** `piolium/findings-draft/p10-001-instance-name-path-traversal.md`
- **Adversarial Review:** `piolium/adversarial-reviews/p10-001-instance-name-path-traversal-review.md` — CONFIRMED, severity challenge rejected
#### Attack Pattern: AP-001
This finding is the root of attack pattern **AP-001** (Path Traversal via Unsanitized Instance Name), which has 12 confirmed instances across 4 route modules:
- `src/routes/instances.rs:205` (create_dir_all)
- `src/routes/instances.rs:392` (remove_dir_all)
- `src/routes/mods.rs:126` (mods dir creation)
- `src/routes/mods.rs:343` (mod rescan)
- `src/routes/mods.rs:394` (mod delete)
- `src/routes/backups.rs:107` (backup path)
- `src/routes/instances.rs:593` (world export)
- `src/routes/instances.rs:739` (server.properties)
- `src/routes/instances.rs:672` (world import — variant)
- `src/routes/instances.rs:776` (regenerate world — variant)
- `src/routes/players.rs:53` (player management — variant)
- `src/routes/backups.rs:112` (backup create — variant)
#### Variants
| Variant ID | Title | Severity | Location | Flow |
|-----------|-------|----------|----------|------|
| p12-001 | World Import Path Traversal | HIGH | `instances.rs:672` | `instance_name` from DB → `world_dir.join(zip_entry)` → `File::create()` |
| p12-002 | Regenerate World Path Traversal | HIGH | `instances.rs:776` | `instance_name` from DB → `.join(&name)` → `remove_dir_all(world_dir)` |
| p12-003 | Player Management Path Traversal | MEDIUM | `players.rs:53` | `inst_name` → `.join(...)` → `read_json_list()` (read-only, 3 filenames) |
| p12-004 | Backup Create Path Traversal | MEDIUM | `backups.rs:112` | `name` → `{name}_{timestamp}.zip` → `.join(&filename)` → `File::create()` |
Variant details: `piolium/findings-draft/p12-001-*.md` through `piolium/findings-draft/p12-004-*.md`
---
### Level-Seed Properties Injection (p10-003 — HIGH)
- **Severity:** HIGH
- **Summary:** The `POST /instances/{id}/world/regenerate` handler writes the user-supplied `seed` value into `server.properties` via line-based replacement with no escaping. Newline characters in the seed inject arbitrary Java `.properties` entries.
- **Impact:** Persistent modification of Minecraft server configuration:
- Set `online-mode=false` (disable authentication — any player can join as anyone)
- Set `enforce-whitelist=false` (bypass whitelist restrictions)
- Change difficulty, gamemode, max-players, PvP settings
- Inject malformed properties causing server startup failure (DoS)
- **Persistence:** Injected values survive across server restarts until manually cleaned
- **Root Cause:** `format!("level-seed={seed}")` writes the seed value directly into `server.properties` without escaping. The Java `.properties` spec treats newlines as property separators. The `properties.rs:13-19` reader also lacks escape-sequence processing (spec gap G1).
- **Key Code Reference:** `src/routes/instances.rs:715-759` — `regenerate_world` handler, line replacement loop
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-003-level-seed-properties-injection.md`
- **Adversarial Review:** `piolium/adversarial-reviews/p10-003-level-seed-properties-injection-review.md` — CONFIRMED, severity unchanged
---
### Missing CSRF Protection (p10-005 — HIGH)
- **Severity:** HIGH (adversarial challenge to MEDIUM rejected)
- **Summary:** The application has no CSRF protection across any of its 31 POST endpoints. No CSRF tokens are generated or validated. No Origin/Referer header validation exists. The session cookie uses `SameSite=Lax` which permits cookies on top-level cross-site POST navigations.
- **Impact:** Universal cross-site request forgery enabling:
- **Account takeover:** Cross-site password change (though `current_password` IS required for `/change-password`, the superuser `/accounts/set-password` does NOT require the current password)
- **Instance destruction:** Cross-site delete requests wipe server data
- **File system manipulation:** CSRF + path traversal (p10-001) to write files to arbitrary locations
- **Minecraft server compromise:** CSRF to op attackers on the Minecraft server via player management endpoints
- **Malicious mod upload:** Cross-site mod upload writes JAR files to server
- **Root Cause:** Cookie `SameSite=Lax` (not `Strict`) and zero CSRF token infrastructure. No axum CSRF middleware, no custom token generation, no header validation.
- **Key Code Reference:** `src/auth.rs:83-86` — Cookie with `SameSite=Lax`; entire `src/routes/mod.rs` — no CSRF middleware
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-005-missing-csrf-protection.md`
- **Adversarial Review:** `piolium/adversarial-reviews/p10-005-missing-csrf-protection-review.md` — CONFIRMED; severity down-challenge from HIGH to MEDIUM rejected by chamber (sub-claim D partially false but overall impact remains HIGH)
---
### RCON Command Injection (p10-002 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** The `player_action!` macro in `src/routes/players.rs` constructs RCON commands by interpolating user-supplied usernames via `format!()` without sanitization. Six player management endpoints are affected.
- **Impact:** Operation-target manipulation via space injection, silent operation failure from malformed usernames. In vanilla Minecraft, RCON does not support command chaining (no `;` or `&&` injection), limiting impact to argument injection. On Spigot/Paper servers with command-chaining plugins, broader injection may be possible.
- **Root Cause:** `format!("whitelist add {}", form.username)` — no validation, no character filtering, no Minecraft username format enforcement.
- **Key Code Reference:** `src/routes/players.rs:89-102` — `player_action!` macro; `PlayerAction.username` is a raw `String`
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-002-rcon-command-injection.md`
---
### Flat Authorization Model (p10-010 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** Any authenticated user has full access to ALL instances, mods, backups, and player operations. There is no per-resource ownership, no role granularity beyond binary superuser/non-superuser, and no instance-level authorization.
- **Impact:** In multi-user deployments, every user is a full administrator of every server instance. Data exfiltration, destructive operations, and Minecraft server control are all available to any authenticated account.
- **Root Cause:** No `owner_id` column on `instances` table; all handlers use `CurrentUser(_user)` with destructured-and-ignored user variable; all queries lack user-scoped filters.
- **Key Code References:** `src/routes/instances.rs` (all handlers), `src/routes/players.rs` (`player_action!`), `src/routes/backups.rs`, `src/routes/mods.rs`
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-010-flat-authorization-model.md`
---
### No Server-Side Session TTL (p10-006 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** The `require_auth` middleware validates session cookies against the database but never checks the `created_at` timestamp, despite the column existing in the schema. Stolen session cookies remain valid indefinitely server-side.
- **Root Cause:** `WHERE s.id = ?1` query at `src/auth.rs:108-115` lacks a time-based filter. Cookie Max-Age=86400 is client-side only and trivially bypassed.
- **Key Code Reference:** `src/auth.rs:108-115` — session query without `created_at` filter
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-006-no-server-side-session-ttl.md`
---
### No Rate Limiting Login (p10-007 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** `POST /login` has no rate limiting, account lockout, or progressive delay. Argon2id (~100ms/attempt) provides a weak mitigating factor.
- **Root Cause:** No rate-limiting middleware, no `governor` or equivalent crate in Cargo.toml.
- **Key Code Reference:** `src/auth.rs:39-92` — authenticate handler; `src/routes/mod.rs:44` — route registration
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-007-no-rate-limiting-login.md`
---
### Background Task Stale is_active (p10-011 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** `activate_instance` spawns a background tokio task that updates `container_state` using `WHERE is_active = 1` instead of the concrete instance ID. If the user switches active instances during the 60-second polling window, the stale task writes to the wrong instance's state.
- **Root Cause:** 5 UPDATE statements at `src/routes/instances.rs:457-502` all use `WHERE is_active = 1` instead of `WHERE id = ?1`.
- **Key Code Reference:** `src/routes/instances.rs:457-502` — background tokio task
- **PoC Status:** draft-only (requires dynamic test)
- **Detailed Report:** `piolium/findings-draft/p10-011-background-task-stale-is-active.md`
---
### Delete-Create Name Reuse Race (p10-012 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** `delete_instance` releases the DB mutex before `remove_dir_all`. A concurrent `create_instance` with the same name can create a new instance whose data directory is then wiped by the still-running deletion.
- **Root Cause:** Mutex released at `drop(conn)` between `DELETE FROM instances` and `remove_dir_all()` (microsecond-to-millisecond race window).
- **Key Code Reference:** `src/routes/instances.rs:360-396`
- **PoC Status:** draft-only (requires dynamic test)
- **Detailed Report:** `piolium/findings-draft/p10-012-delete-create-name-reuse-race.md`
---
### No Idempotency (p10-013 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** Zero idempotency infrastructure across all 31 POST endpoints. Network request replay (HTMX retry, proxy retry, rapid clicks) causes duplicate operations.
- **Impact:** Duplicate mod uploads cause classloader conflicts on server restart (DoS). Duplicate backup creation wastes disk space. Duplicate player RCON commands are mostly harmless.
- **Root Cause:** No idempotency key table, no deduplication logic, no request ID storage.
- **Key Code Reference:** All POST endpoints in `src/routes/*.rs`
- **PoC Status:** draft-only (static hypothesis)
- **Detailed Report:** `piolium/findings-draft/p10-013-no-idempotency.md`
---
### Mod Validation Denial of Service (p10-016 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** `validate_mod()` parses uploaded JAR constant pools with no timeout or resource limits. A crafted constant pool (cp_count=65535, expensive CONSTANT_Utf8 entries) causes CPU exhaustion on the async runtime.
- **Impact:** Async thread pool exhaustion; multiple concurrent crafted uploads make the server unresponsive.
- **Root Cause:** Unbounded `while i < cp_count` loop at `src/mods.rs:173-232` with no timeout wrapping.
- **Key Code Reference:** `src/mods.rs:173-232` — `scan_single_class()`; `src/routes/mods.rs:109-250` — no timeout around `validate_mod`
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-016-mod-validation-denial-of-service.md`
---
### No Encryption at Rest (p10-017 — MEDIUM)
- **Severity:** MEDIUM
- **Summary:** SQLite database `mcui.db` is stored unencrypted on disk with plaintext RCON passwords. Disclosure via prerequisite file read (p10-001 path traversal) or physical access exposes all secrets.
- **Root Cause:** `Connection::open(path)` at `src/db.rs:16` with no encryption (no SQLCipher, no individual field encryption).
- **Key Code Reference:** `src/db.rs:16` — `Connection::open(path)`
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-017-no-encryption-at-rest.md`
---
### Logout No Auth Middleware (p10-008 — LOW)
- **Severity:** LOW
- **Summary:** `POST /logout` is registered outside the `require_auth` protected router group. Any unauthenticated request can reach the logout handler. Requires prior session ID disclosure (UUIDv4, 122-bit entropy) for practical exploitation.
- **Key Code Reference:** `src/routes/mod.rs:20-33` — logout registered before `.merge(protected)`
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-008-logout-no-auth-middleware.md`
---
### Cookie No Secure Flag (p10-009 — LOW)
- **Severity:** LOW
- **Summary:** Session cookie lacks `Secure` flag. With localhost-bound traffic behind an HTTPS-terminating reverse proxy, the cookie travels unencrypted between proxy and app.
- **Key Code Reference:** `src/auth.rs:83-86` — cookie string missing `; Secure`
- **PoC Status:** draft-only
- **Detailed Report:** `piolium/findings-draft/p10-009-cookie-no-secure-flag.md`
---
### Mod Write Before DB Orphan (p10-014 — LOW)
- **Severity:** LOW
- **Summary:** `process_jar_upload` writes the mod file to disk before inserting the DB record. A crash between these operations orphans the file (invisible to UI, never cleaned up).
- **Key Code Reference:** `src/routes/mods.rs:234-260`
- **PoC Status:** draft-only (static hypothesis)
- **Detailed Report:** `piolium/findings-draft/p10-014-mod-write-before-db-orphan.md`
---
### Backup Orphan Race (p10-015 — LOW)
- **Severity:** LOW
- **Summary:** `create_backup` creates the ZIP file before inserting the DB record. Concurrent instance deletion during ZIP creation causes a silently-swallowed FK violation, leaving orphaned ZIP files on disk.
- **Key Code Reference:** `src/routes/backups.rs:85-139`
- **PoC Status:** draft-only (requires dynamic test)
- **Detailed Report:** `piolium/findings-draft/p10-015-backup-orphan-race.md`
---
## Attack Surface Summary
The complete attack surface inventory is documented at:
| Artifact | Path | Description |
|----------|------|-------------|
| **Knowledge Base Report** | `piolium/attack-surface/knowledge-base-report.md` | Full architecture model, DFD/CFD slices, trust boundaries, component inventory (18 sections) |
| **Attack Pattern Registry** | `piolium/attack-pattern-registry.json` | 5 confirmed attack patterns (AP-001 through AP-005) with 12+32+1+31+1=77 total confirmed instances |
| **Manual Attack Surface Inventory** | `piolium/attack-surface/manual-attack-surface-inventory.md` | 38 HTTP routes catalogued with entry points, sinks, trust boundaries |
| **Source-Sink Flow Paths** | `piolium/attack-surface/source-sink-flows-all-severities.md` | All data flow paths from attacker input to dangerous sinks |
| **Unauthenticated Surface** | `piolium/attack-surface/unauthenticated-surface.md` | Routes accessible without authentication |
| **Spec Gap Summary** | `piolium/attack-surface/spec-gap-summary.md` | RFC/contract gaps (Java .properties, Argon2, RCON protocol, Axum contracts) |
| **Variant Analysis Summary** | `piolium/attack-surface/variant-summary.md` | Phase 12 variant search results |
| **State/Concurrency Summary** | `piolium/attack-surface/state-concurrency-summary.md` | Race conditions, TOCTOU, ordering bugs |
| **Advisory Summary** | `piolium/attack-surface/advisory-summary.md` | External advisory intelligence |
| **SBOM** | `piolium/attack-surface/sbom.json` | Software bill of materials |
| **Patch Bypass Summary** | `piolium/attack-surface/patch-bypass-summary.md` | Prior-sec patch regression analysis |
### Key Attack Surface Dimensions
1. **38 HTTP routes** — 3 public POST, 1 public GET, 31 authenticated POST, 3 authenticated GET
2. **5 attacker-controlled input sources** — form fields (instance name, seed, username, motd), multipart uploads (JAR/ZIP files), path parameters (instance ID, backup ID, mod ID), cookie header, outbound Mojang API response
3. **4 dangerous sinks** — filesystem (create_dir_all, remove_dir_all, File::create, read_to_string), RCON TCP (send_command_async), Docker Unix socket (bollard API), SQLite (rusqlite)
4. **3 trust boundaries** — unauthenticated→authenticated (session cookie), webUI→filesystem (path traversal), webUI→RCON/Minecraft (command injection)
---
## Coverage Gaps
### Pipeline Failure: Findings Never Promoted
The most significant gap is that **the findings promotion pipeline terminated prematurely** between Phase 12 (variant analysis) and Phase 15 (report assembly):
- `piolium/findings/` — **does not exist** — no finding was ever promoted from draft
- No PoC scripts were built for any finding
- No `report.md` files were generated with structured severity/PoC/evidence sections
- No execution evidence was collected
- Only 4 of 17 findings received adversarial review (P11 cold verification)
- No `metadata.json` files were created for variant-parent tracking
- Validating script (`validate_phase_output.py`) not present at expected path
### Static Analysis Gaps
- **CodeQL database could not be built** — the Rust analyzer version mismatch prevented database construction. Only structural extraction (call graphs, entry points, sinks) was performed from manual review.
- **Semgrep Pro** not available — cross-file taint analysis was not performed for Rust
- **No automated sink-to-source tracing** — all data flow mapping was manual
### Multi-User Deployment Not Analyzed for Scale
- The flat authorization model (p10-010) was assessed as MEDIUM based on single-user assumptions
- In a multi-user deployment (2+ users), the severity of p10-010 + p10-001 + p10-005 escalates to CRITICAL
- No instance-level access control, audit logging, or rate limiting for user actions
### Encryption & Key Management
- No encryption at rest (p10-017)
- RCON passwords stored in plaintext
- No TLS termination handled by the application (delegated to reverse proxy)
- Session IDs stored in unencrypted SQLite
### Supply Chain Not Scanned
- 19 Rust crate dependencies listed in SBOM but no automated vulnerability scan (cargo-audit not integrated)
- Outbound Mojang API calls not constrained (no TLS pinning, no timeout documented)
---
## Methodology Notes
### Chamber Workspace Summary
The Phase 10 adversarial review chamber processed 37 finding candidates across 6 clusters:
| Cluster | Attack Class | Candidates | Valid Survivors | Rejected |
|---------|-------------|-----------|-----------------|----------|
| path-traversal | Path Traversal & File System | 7 | 1 (H-01) | 6 |
| injection | Injection (RCON, Docker, Properties) | 5 | 2 (H-08, H-10) | 3 |
| auth-session | Auth & Session Management | 9 | 4 (H-13, H-14, H-16, H-17) | 5 |
| state-concurrency | State & Concurrency | 6 | 5 | 1 |
| denial-of-service | Denial of Service | 4 | 1 (H-28) | 3 |
| security-architecture | Security Architecture | 6 | 1 (H-33) | 5 |
| **Total** | | **37** | **17** | **20** |
**Rejection breakdown:** 7 FALSE POSITIVE, 8 DROP, 5 DUPLICATE
### Cold Verification (P11)
4 findings subjected to adversarial review:
- **p10-001** (Instance Name Path Traversal): CONFIRMED — severity HIGH→HIGH (no change)
- **p10-003** (Level-Seed Properties Injection): CONFIRMED — severity HIGH→HIGH (no change)
- **p10-004** (RCON Password Exposed): DISPROVED — password never rendered in edit.html template (Askama explicit-field model)
- **p10-005** (Missing CSRF Protection): CONFIRMED — severity HIGH→MEDIUM challenged, rejected by chamber (CSRF+chain attacks warrant HIGH)
### Variant Analysis (P12)
4 new variant instances discovered from AP-001 root cause search:
- All 4 come from instance name path traversal pattern
- Zero variants found for the remaining 13 findings
- The path traversal pattern (AP-001) is the most pervasive vulnerability class with 12 total confirmed instances
### Attack Pattern Registry
5 attack patterns documented in `piolium/attack-pattern-registry.json`:
- AP-001: Path Traversal via Unsanitized Instance Name (12 instances)
- AP-002: RCON Command Injection via Unsanitized Username (6 instances)
- AP-003: Java Properties Injection via Unsanitized Seed Value (1 instance)
- AP-004: Missing CSRF Protection (31 endpoints)
- AP-005: No Server-Side Session TTL Enforcement (1 query)
---
## Conclusion
This audit catalogued 17 validated vulnerabilities across the minecraft-ui codebase. The most severe class — **path traversal via unsanitized instance names** — creates a systemic risk: any authenticated user can read, write, and delete files anywhere the webUI process can access. The absence of CSRF protection (31 endpoints) and per-resource authorization means that a single compromised account (or a cross-site request from a victim's browser) grants full control over all server instances, their files, and their Minecraft consoles.
The application's security posture is appropriate _only_ for its documented single-user, localhost-only deployment model. Any deployment that:
- Exposes the WebUI beyond localhost
- Adds a second user account
- Sits behind a reverse proxy without CSRF middleware at the proxy layer
- Does not validate instance names at the input layer
...faces unacceptable risk of data loss, privilege escalation, and persistent compromise.
**Pipeline note:** The audit's findings-draft→findings promotion failed. The 17 validated findings, 4 variants, and 5 attack patterns documented in this report are derived from draft-level analysis without confirmed PoC execution. A follow-up audit should focus on building working PoCs for the critical and high-severity findings and executing them against a deployed instance to confirm exploitability and impact in a real environment.
---
## Deferred Findings (triage skip)
*No findings were triaged to `piolium/findings-deferred/`. The `piolium/findings-deferred/` directory does not exist because no findings were promoted past the draft stage. All 17 validated findings remain at investigative (draft) status.*
|