diff options
Diffstat (limited to '')
| -rw-r--r-- | piolium/attack-surface/state-concurrency-summary.md | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/piolium/attack-surface/state-concurrency-summary.md b/piolium/attack-surface/state-concurrency-summary.md new file mode 100644 index 0000000..48677b3 --- /dev/null +++ b/piolium/attack-surface/state-concurrency-summary.md | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | # State & Concurrency Audit | ||
| 2 | |||
| 3 | ## State-Holding Entities Catalogued | ||
| 4 | |||
| 5 | | Entity | Table | State Columns | Allowable Values | Concurrency Risk | | ||
| 6 | |--------|-------|---------------|-----------------|------------------| | ||
| 7 | | Account | `accounts` | `is_superuser` | 0/1 | Low (rarely mutated) | | ||
| 8 | | Account | `accounts` | `password_change_required` | 0/1 | Low | | ||
| 9 | | Session | `sessions` | `created_at` | datetime | **High** — no TTL enforcement | | ||
| 10 | | Instance | `instances` | `is_active` | 0/1 | **CRITICAL** — background task stale writes | | ||
| 11 | | Instance | `instances` | `container_state` | stopped/pulling/booting/running/error | **CRITICAL** — not bound to instance ID in background writes | | ||
| 12 | | Instance | `instances` | `has_modpack` | 0/1 | Medium — RMW across mutex acquisitions | | ||
| 13 | | Instance | `instances` | `name` | TEXT (UNIQUE) | **HIGH** — name-reuse race between delete and create | | ||
| 14 | | Mod | `mods` | `accepted` | 0/1 | Low | | ||
| 15 | | Backup | `backups` | `filename`, `created_at` | TEXT, datetime | Medium — orphan ZIP on concurrent delete | | ||
| 16 | | All | — | — | — | **No idempotency infrastructure** | | ||
| 17 | |||
| 18 | **Total state-holding entities catalogued:** 10 (across 5 tables) | ||
| 19 | |||
| 20 | ## Concurrency Primitives Observed | ||
| 21 | |||
| 22 | | Primitive | Location | Scope | Limitation | | ||
| 23 | |-----------|----------|-------|------------| | ||
| 24 | | `Arc<Mutex<Connection>>` | `src/db.rs:7` | SQLite connection | Serialises per-statement, not per-transaction | | ||
| 25 | | `MutexGuard::drop()` implicit | Every `let conn = state.db.conn()` / `drop(conn)` pattern | Statement boundaries | Mutex released between read and write in multiple handlers | | ||
| 26 | | Tokio async tasks (background spawn) | `src/routes/instances.rs:457` | container lifecycle | **No instance ID binding** — uses `WHERE is_active = 1` | | ||
| 27 | | SQLite WAL mode | `src/db.rs:19` (PRAGMA) | Write-ahead logging | Allows concurrent reads during writes but does not prevent any of the races documented | | ||
| 28 | |||
| 29 | **No distributed locks, no advisory locks, no `SELECT ... FOR UPDATE`, no explicit BEGIN/COMMIT boundaries.** | ||
| 30 | |||
| 31 | ## Idempotency Infrastructure | ||
| 32 | |||
| 33 | **Absent.** No `idempotency_key` table, no deduplication tokens, no request ID storage, no unique constraints leveraged for dedup (except `accounts.username` and `instances.name`). Every POST handler is vulnerable to replay/double-submit. | ||
| 34 | |||
| 35 | ## Drafts Filed | ||
| 36 | |||
| 37 | | Draft | Severity | Class | Summary | | ||
| 38 | |-------|----------|-------|---------| | ||
| 39 | | p6-001 | CRITICAL | toctou | Background task in `activate_instance` uses `WHERE is_active = 1` (no instance ID bound). After deactivation/reactivation, stale task writes `container_state` on the wrong instance. | | ||
| 40 | | p6-002 | HIGH | toctou | `delete_instance` releases DB mutex before `remove_dir_all`. Concurrent `create_instance` with same name has its data directory wiped. Cross-resource TOCTOU with data loss. | | ||
| 41 | | p6-003 | MEDIUM | state-machine-violation | `edit_instance` stops container on active instances without restarting. `is_active=1` and stale `container_state='running'` persist. Instance appears running but isn't. | | ||
| 42 | | p6-004 | HIGH | idempotency | No idempotency infrastructure on any POST handler. Mod upload, backup create, login, account create all vulnerable to replay/double-submit. | | ||
| 43 | | p6-005 | MEDIUM | rmw-no-txn | `process_jar_upload` writes file to disk before DB INSERT. Crash between file write and DB insert leaves orphaned mod file. Also performs `has_modpack` update across separate mutex acquisition. | | ||
| 44 | | p6-006 | MEDIUM | toctou | `create_backup` reads instance name, releases mutex, creates ZIP file (long I/O window), then re-acquires mutex. Concurrent instance deletion causes FK violation — orphaned ZIP file with no DB record. | | ||
| 45 | |||
| 46 | **Total draft findings filed: 6** \ No newline at end of file | ||
