diff options
| author | salmonik <salmonik@tuta.io> | 2026-07-29 02:24:41 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-07-29 02:24:41 +0200 |
| commit | c654a6d17eb58adbb15b9c47ab32bcc3a1666307 (patch) | |
| tree | 545544bf7d805254415da787fad1cdc711767833 /src/routes/mod.rs | |
| parent | Add per-instance mod management with client-side detection (diff) | |
| download | minecraft-ui-c654a6d17eb58adbb15b9c47ab32bcc3a1666307.tar.gz minecraft-ui-c654a6d17eb58adbb15b9c47ab32bcc3a1666307.zip | |
Security audit fixes: patch 16 vulnerabilities across 7 source files
CRITICAL:
- Instance name path traversal (AP-001): sanitize::sanitize_instance_name()
strips .., /, \, \0, spaces, special chars at all 12 join call sites
- Zip-slip protection in world import: starts_with() guard after enclosed_name()
HIGH:
- RCON command injection: validate_username() rejects non-MC usernames
across all 6 player action macros (whitelist, op, ban)
- Level-seed properties injection: sanitize_seed() strips \n \r = : \0
- CSRF protection: SameSite=Lax -> SameSite=Strict on session cookie
MEDIUM:
- Session TTL: server-side 24h expiry via strftime check in require_auth
- Rate limiting: in-memory 10-ip/5min sliding window on login
- Background task stale is_active: all queries use concrete WHERE id=?1
- Mod validation DoS: 500MB cap, 10k class scan limit, 10k CP entry cap
LOW:
- Logout auth guard: moved into protected route group + CurrentUser param
- Mod orphan race: DB insert before file write
- Backup orphan race: DB insert before ZIP creation
- Template fix: broken Askama == comparisons in edit.html
All fixes compile clean with zero warnings. 10 unit tests pass.
Diffstat (limited to '')
| -rw-r--r-- | src/routes/mod.rs | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/routes/mod.rs b/src/routes/mod.rs index a4d200c..2029bf8 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs | |||
| @@ -31,6 +31,7 @@ pub fn build_router(state: AppState) -> Router { | |||
| 31 | "/change-password", | 31 | "/change-password", |
| 32 | axum::routing::post(accounts::change_password), | 32 | axum::routing::post(accounts::change_password), |
| 33 | ) | 33 | ) |
| 34 | .route("/logout", axum::routing::post(crate::auth::logout)) | ||
| 34 | .merge(dashboard::router()) | 35 | .merge(dashboard::router()) |
| 35 | .merge(instances::router()) | 36 | .merge(instances::router()) |
| 36 | .merge(players::router()) | 37 | .merge(players::router()) |
| @@ -42,7 +43,6 @@ pub fn build_router(state: AppState) -> Router { | |||
| 42 | Router::new() | 43 | Router::new() |
| 43 | .route("/login", axum::routing::get(login_page)) | 44 | .route("/login", axum::routing::get(login_page)) |
| 44 | .route("/login", axum::routing::post(crate::auth::authenticate)) | 45 | .route("/login", axum::routing::post(crate::auth::authenticate)) |
| 45 | .route("/logout", axum::routing::post(crate::auth::logout)) | ||
| 46 | .merge(protected) | 46 | .merge(protected) |
| 47 | .nest_service("/static", ServeDir::new("static")) | 47 | .nest_service("/static", ServeDir::new("static")) |
| 48 | .with_state(state) | 48 | .with_state(state) |
