# Architecture Entrypoints Inventory **Target:** salmon/minecraft-ui **Generated:** 2025-07-29 **Phase:** P3 --- ## Public Routes (No Auth Required) | # | Method | Path | Handler | Source file | Parameters | Attacker-controlled sources | |---|--------|------|---------|-------------|------------|---------------------------| | 1 | GET | `/login` | `login_page` | src/routes/mod.rs:43 | None | None | | 2 | POST | `/login` | `authenticate` | src/auth.rs:34 | `username`, `password` (Form) | `username`, `password` strings | | 3 | POST | `/logout` | `logout` | src/auth.rs:130 | Cookie header (optional) | Session ID from cookie | | 4 | GET | `/static/*` | `ServeDir` | src/routes/mod.rs:28 | File path | Static file path (ServeDir) | ## Protected Routes (Auth Required via `require_auth` middleware) ### Dashboard | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 5 | GET | `/` | `dashboard` | src/routes/dashboard.rs:19 | Session cookie → CurrentUser | ### Instance Management | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 6 | GET | `/instances` | `list_instances` | src/routes/instances.rs:44 | None | | 7 | GET | `/instances/new` | `create_form` | src/routes/instances.rs:70 | None | | 8 | POST | `/instances/new` | `create_instance` | src/routes/instances.rs:87 | `name`, `version`, `server_type`, `world_source`, `seed`, `memory_mb`, `difficulty`, `gamemode`, `max_players`, `pvp`, `motd` | | 9 | GET | `/instances/{id}/edit` | `edit_form` | src/routes/instances.rs:129 | Path: `id` (i64) | | 10 | POST | `/instances/{id}/edit` | `edit_instance` | src/routes/instances.rs:176 | Path: `id`; Form: `difficulty`, `gamemode`, `max_players`, `pvp`, `whitelist_enabled`, `motd`, `memory_mb` | | 11 | POST | `/instances/{id}/delete` | `delete_instance` | src/routes/instances.rs:198 | Path: `id` | | 12 | POST | `/instances/{id}/activate` | `activate_instance` | src/routes/instances.rs:217 | Path: `id` | | 13 | POST | `/instances/deactivate` | `deactivate_instance` | src/routes/instances.rs:278 | None | ### World Management | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 14 | GET | `/instances/{id}/world/export` | `export_world` | src/routes/instances.rs:288 | Path: `id` | | 15 | POST | `/instances/{id}/world/import` | `import_world` | src/routes/instances.rs:328 | Path: `id`; Multipart: ZIP file | | 16 | POST | `/instances/{id}/world/regenerate` | `regenerate_world` | src/routes/instances.rs:360 | Path: `id`; Form: `seed` | ### Player Management | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 17 | GET | `/players` | `manage_players` | src/routes/players.rs:28 | None | | 18 | POST | `/players/whitelist/add` | `add_whitelist` | src/routes/players.rs:89 | `username` | | 19 | POST | `/players/whitelist/remove` | `remove_whitelist` | src/routes/players.rs:89 | `username` | | 20 | POST | `/players/op/add` | `add_op` | src/routes/players.rs:89 | `username` | | 21 | POST | `/players/op/remove` | `remove_op` | src/routes/players.rs:89 | `username` | | 22 | POST | `/players/ban/add` | `add_ban` | src/routes/players.rs:89 | `username` | | 23 | POST | `/players/ban/remove` | `remove_ban` | src/routes/players.rs:89 | `username` | ### Backup Management | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 24 | GET | `/instances/{id}/backups` | `list_backups` | src/routes/backups.rs:30 | Path: `id` | | 25 | POST | `/instances/{id}/backups/create` | `create_backup` | src/routes/backups.rs:54 | Path: `id` | | 26 | POST | `/backups/{id}/restore` | `restore_backup` | src/routes/backups.rs:88 | Path: `id` (STUB — no-op) | | 27 | GET | `/backups/{id}/download` | `download_backup` | src/routes/backups.rs:93 | Path: `id` | ### Mod Management | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 28 | GET | `/instances/{id}/mods` | `list_mods` | src/routes/mods.rs:42 | Path: `id` | | 29 | POST | `/instances/{id}/mods` | `upload_mod` | src/routes/mods.rs:86 | Path: `id`; Multipart: `.jar`/`.zip` file + filename | | 30 | POST | `/instances/{id}/mods/{mod_id}/delete` | `delete_mod` | src/routes/mods.rs:188 | Path: `instance_id`, `mod_id` | | 31 | POST | `/instances/{id}/mods/rescan` | `rescan_mods` | src/routes/mods.rs:163 | Path: `id` | ### Account Management (Superuser only — guarded in handler) | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 32 | GET | `/accounts` | `manage_accounts` | src/routes/accounts.rs:60 | None | | 33 | POST | `/accounts/create` | `create_account` | src/routes/accounts.rs:95 | `username`, `password`, `is_superuser` | | 34 | POST | `/accounts/delete` | `delete_account` | src/routes/accounts.rs:111 | `id` | | 35 | POST | `/accounts/set-password` | `set_password` | src/routes/accounts.rs:142 | `id`, `new_password` | | 36 | POST | `/accounts/change-own-password` | `change_own_password_from_accounts` | src/routes/accounts.rs:163 | `current_password`, `new_password` | ### Password Change (accessible before password_change_required satisfied) | # | Method | Path | Handler | Source file | Key inputs | |---|--------|------|---------|-------------|------------| | 37 | GET | `/change-password` | `change_password_page` | src/routes/mod.rs:58 | Session cookie → CurrentUser | | 38 | POST | `/change-password` | `accounts::change_password` | src/routes/mod.rs:65 | Session cookie; Form: `current_password`, `new_password` | --- ## Attacker-Controlled Sources Summary | Source category | Examples | Highest risk sink | |-----------------|----------|-------------------| | Form fields (strings) | `username`, `name`, `seed`, `motd` | SQLite INSERT/UPDATE (parametrized), RCON command (unsanitized) | | Multipart file bytes | `.jar`/`.zip` uploads | Filesystem write via `std::fs::write` | | Multipart filename | `field.file_name()` | Filesystem path construction | | Path parameters | `id`, `instance_id`, `mod_id` | SQL queries (parametrized), filesystem paths (backup download) | | Cookie header | `mcui_session` | Session lookup (parametrized) | --- ## High-Value Sinks | Sink category | Locations | Risk | |--------------|-----------|------| | **Filesystem write** | `src/routes/mods.rs:98` (`std::fs::write`); `src/routes/instances.rs:210` (`std::fs::File::create`); `src/routes/backups.rs:72` (`std::fs::File::create`) | **HIGH** — arbitrary file write from mod upload | | **Filesystem read** | `src/routes/backups.rs:106` (`std::fs::read`); `src/routes/instances.rs:293` (`std::fs::read`) | MEDIUM — arbitrary file read | | **Docker control** | `src/docker.rs:62` (`start_container`); `src/docker.rs:106` (`stop_container`) | **HIGH** — container lifecycle | | **RCON command** | `src/routes/players.rs:89` (`client.send_command_async(cmd)`); `src/routes/instances.rs:153` (`send_command_async`) | **HIGH** — Minecraft server control | | **SQL execution** | All `execute()` and `query_row()` calls (parametrized) | LOW — parametrized | | **TLS outbound** | `src/routes/instances.rs:280` (`reqwest::Client` → Mojang API) | LOW — trusted URL | --- ## Key Source Files | File | Role | Security relevance | |------|------|-------------------| | `src/auth.rs` | Auth middleware, login/logout, session management | **CRITICAL** — auth boundary | | `src/routes/mod.rs` | Router builder, route composition | **CRITICAL** — which routes are protected | | `src/routes/mods.rs` | Mod upload, ZIP extraction, validation | **HIGH** — file write, parsing | | `src/routes/instances.rs` | Instance CRUD, world import/export, container | **HIGH** — ZIP extraction, file ops | | `src/routes/backups.rs` | Backup create/download/restore | **MEDIUM** — file read/write | | `src/routes/players.rs` | RCON whitelist/op/ban commands | **MEDIUM** — RCON injection | | `src/routes/accounts.rs` | Account CRUD, password change | **HIGH** — privilege management | | `src/mods.rs` | JAR metadata + class-file validation | **HIGH** — parsing attacker-supplied JARs | | `src/rcon.rs` | RCON protocol client | **MEDIUM** — Minecraft server control | | `src/docker.rs` | Docker container lifecycle | **HIGH** — host-level operations | | `src/db.rs` | Database schema + connection | **MEDIUM** — schema design | | `src/config.rs` | Configuration loading | **MEDIUM** — initial creds | | `src/properties.rs` | .properties file reader | **LOW** |