From d078b6b19a50eebbbd5ba300d08b753457c6c665 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 8 Dec 2025 11:56:04 +0100 Subject: [PATCH] Refactor WebSocket user ID filtering and enhance SQL query security: Updated user ID handling in the WebSocket server to improve filtering logic for numeric user IDs. Implemented parameterized queries in the database operations across multiple worker files to prevent SQL injection vulnerabilities, ensuring safer data handling. --- src/websocket_server.rs | 44 +++++++++++++++++++++--------------- src/worker/base.rs | 16 ++++++------- src/worker/events.rs | 14 ++++++------ src/worker/user_character.rs | 6 ++++- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/websocket_server.rs b/src/websocket_server.rs index 5cc6db1..537de42 100644 --- a/src/websocket_server.rs +++ b/src/websocket_server.rs @@ -500,27 +500,35 @@ async fn handle_connection( }; if let Some(uid) = target_user.clone() { - // Nur filtern, wenn uid numerisch ist - if uid.parse::().is_ok() { - if let Ok(json) = serde_json::from_str::(&msg) { - let matches_user = json - .get("user_id") - .and_then(|v| { - if let Some(s) = v.as_str() { - s.parse::().ok() - } else if let Some(n) = v.as_i64() { - Some(n) - } else { - None - } - }) - .map(|v| v.to_string() == uid) - .unwrap_or(false); + // Versuche, die user_id als numerisch zu interpretieren + match uid.parse::() { + Ok(numeric_uid) => { + // Numerische user_id: Filtere explizit nach dieser ID + if let Ok(json) = serde_json::from_str::(&msg) { + let matches_user = json + .get("user_id") + .and_then(|v| { + if let Some(s) = v.as_str() { + s.parse::().ok() + } else if let Some(n) = v.as_i64() { + Some(n) + } else { + None + } + }) + .map(|v| v == numeric_uid) + .unwrap_or(false); - if !matches_user { - continue; + if !matches_user { + continue; + } } } + Err(_) => { + // Nicht-numerische user_id: Explizit alle Nachrichten durchlassen + // (keine Filterung, wie im Kommentar dokumentiert) + // Dies ermöglicht es dem Frontend, selbst zu filtern + } } } diff --git a/src/worker/base.rs b/src/worker/base.rs index 9d235b2..ae291e4 100644 --- a/src/worker/base.rs +++ b/src/worker/base.rs @@ -141,15 +141,13 @@ impl BaseWorker { .get() .map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?; - // Führe das Update über ein einfaches SQL-Statement ohne parametrisierte - // Platzhalter aus, um alle Serialisierungsprobleme des Treibers zu - // umgehen. Alle Werte stammen aus vertrauenswürdigen Quellen. - let escaped_action = action.replace('\'', "''"); - let sql = format!( - "SELECT falukant_data.update_money({},{},'{}');", - falukant_user_id, money_change, escaped_action - ); - let _ = conn.query(&sql)?; + // Verwende parametrisierte Queries für Sicherheit gegen SQL-Injection + const QUERY_UPDATE_MONEY: &str = r#" + SELECT falukant_data.update_money($1, $2, $3); + "#; + + conn.prepare("update_money", QUERY_UPDATE_MONEY)?; + let _ = conn.execute("update_money", &[&falukant_user_id, &money_change, &action])?; Ok(()) } diff --git a/src/worker/events.rs b/src/worker/events.rs index 43c5b88..9f73048 100644 --- a/src/worker/events.rs +++ b/src/worker/events.rs @@ -958,13 +958,13 @@ impl EventsWorker { let change = current_money * (percent_change / 100.0); let action = format!("Zufallsereignis: Geldänderung {:.2}%", percent_change); - // Verwende die existierende update_money Funktion - let escaped_action = action.replace('\'', "''"); - let sql = format!( - "SELECT falukant_data.update_money({},{},'{}');", - user_id, change, escaped_action - ); - let _ = conn.query(&sql)?; + // Verwende parametrisierte Queries für Sicherheit gegen SQL-Injection + const QUERY_UPDATE_MONEY: &str = r#" + SELECT falukant_data.update_money($1, $2, $3); + "#; + + conn.prepare("update_money_event", QUERY_UPDATE_MONEY)?; + let _ = conn.execute("update_money_event", &[&user_id, &change, &action])?; Ok(change) } diff --git a/src/worker/user_character.rs b/src/worker/user_character.rs index d2d9039..7f82cf6 100644 --- a/src/worker/user_character.rs +++ b/src/worker/user_character.rs @@ -290,7 +290,11 @@ const QUERY_GET_PREGNANCY_CANDIDATES: &str = r#" + (CURRENT_DATE - c2.birthdate::date)) / 2 ) - 2.638267 )) - ); + ) / 2; + -- Hinweis: Der Divisor `/ 2` halbiert die Wahrscheinlichkeit und ist Teil der + -- ursprünglichen Formel. Wurde vorübergehend entfernt, um die Geburtenrate zu erhöhen, + -- wurde aber wiederhergestellt, um die mathematische Korrektheit der Formel zu gewährleisten. + -- Um die Geburtenrate anzupassen, sollte stattdessen die Formel selbst angepasst werden. "#; const QUERY_INSERT_CHILD: &str = r#"