From 27b580d1088e638f383595f73378948937a1c9e2 Mon Sep 17 00:00:00 2001 From: Ente Date: Fri, 9 Jan 2026 23:06:15 +0100 Subject: [PATCH] v8.7.1 Fixes --- CHANGELOG.md | 9 ++++++++- VERSION | 2 +- api/v1/class/arbeitszeit.inc.php | 4 ++-- api/v1/class/auth/auth.arbeit.inc.php | 2 +- api/v1/class/benutzer/benutzer.arbeit.inc.php | 11 +++++++++++ .../PDFExportModule/PDFExportModule.em.arbeit.inc.php | 2 +- api/v1/class/mode/mode.arbeit.inc.php | 1 - .../class/notifications/notifications.arbeit.inc.php | 4 ++-- composer.json | 2 +- suite/actions/auth/login.php | 2 +- update.sh | 1 + 11 files changed, 29 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a487e6c..f5873dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,17 @@ # CHANGELOG +## v8.7.1 + +* Fixed issues regarding XSS vulnerabilities on several pages. +* Removed echo statements from "normal" mode used for debugging purposes. +* Fixed a bug that allowed to create multiple users with the same username. +* Fixed undefined variables upon login. + ## v8.7 * Added automatic update check within the Settings page allowing to see the changelogs and a link to the new Release. * Updated `README.md` -* Admins can now select the default worktime type to be selected in the form within the app.json `config` section via the `default_worktime_type` key. +* Admins can now select the default worktime type to be selected in the web form within the app.json `config` section via the `default_worktime_type` key. * Added function to automatically add keys to app.json after update * Admins can now customize the look and feel of the PDF exports. Please check `README.md` `Exports` section for more information. diff --git a/VERSION b/VERSION index 12b73c3..3b5f5a0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.7 +8.7.1 diff --git a/api/v1/class/arbeitszeit.inc.php b/api/v1/class/arbeitszeit.inc.php index 73477bb..1ea2a06 100644 --- a/api/v1/class/arbeitszeit.inc.php +++ b/api/v1/class/arbeitszeit.inc.php @@ -629,7 +629,7 @@ public function get_specific_worktime_html(int $month, int $year) $raw = @strftime("%d.%m.%Y", strtotime($row["schicht_tag"])); $rew = $row["schicht_anfang"]; $rol = $row["schicht_ende"]; - $rum = $row["ort"]; + $rum = $this->i18n()->sanitizeOutput($row["ort"]); $rqw = $row["id"]; $rbn = $row["username"]; $rtn = $this->type_from_int($row["Wtype"]) ?? "N/A"; @@ -697,7 +697,7 @@ public function get_employee_worktime_html($username) $raw = @strftime("%d.%m.%Y", strtotime($row["schicht_tag"])); $rew = $row["schicht_anfang"]; $rol = $row["schicht_ende"]; - $rum = $row["ort"]; + $rum = $this->i18n()->sanitizeOutput($row["ort"]); $rqw = $row["id"]; $rtn = $this->type_from_int($row["Wtype"]) ?? "N/A"; $rps = @strftime("%H:%M", strtotime($row["pause_start"])); diff --git a/api/v1/class/auth/auth.arbeit.inc.php b/api/v1/class/auth/auth.arbeit.inc.php index 277436c..f5f80ae 100644 --- a/api/v1/class/auth/auth.arbeit.inc.php +++ b/api/v1/class/auth/auth.arbeit.inc.php @@ -104,7 +104,7 @@ public static function login($username, $password, $option){ # "option"-> array goto nfclogin; } if(password_verify($password, $data["password"])){ - if($option["nfclogin"]){ + if(isset($option["nfclogin"])){ nfclogin: Exceptions::error_rep("Authenticated user via NFC login '" . $username . "'"); } diff --git a/api/v1/class/benutzer/benutzer.arbeit.inc.php b/api/v1/class/benutzer/benutzer.arbeit.inc.php index d7dd5df..4846d45 100644 --- a/api/v1/class/benutzer/benutzer.arbeit.inc.php +++ b/api/v1/class/benutzer/benutzer.arbeit.inc.php @@ -28,6 +28,10 @@ public function create_user($username, $name, $email, $password, $isAdmin = 0) if ($this->nodes()->checkNode("benutzer.inc", "create_user") == false) { return false; } + if($this->user_exists($username)){ + Exceptions::error_rep("User '$username' already exists."); + return false; + } Exceptions::error_rep("Creating user '$username'..."); $password = password_hash($password, PASSWORD_DEFAULT); $sql = "INSERT INTO `users` (`name`, `username`, `email`, `password`, `email_confirmed`, `isAdmin`) VALUES (?, ?, ?, ?, '1', ?);"; @@ -145,6 +149,13 @@ public static function get_user($username) } } + public function user_exists($username){ + if(!is_array($this->get_user($username))){ + return false; + } + return true; + } + /** * get_user_from_id() - Gets a user from the database * @param int $id diff --git a/api/v1/class/exports/modules/PDFExportModule/PDFExportModule.em.arbeit.inc.php b/api/v1/class/exports/modules/PDFExportModule/PDFExportModule.em.arbeit.inc.php index 3de0d85..4a59acf 100644 --- a/api/v1/class/exports/modules/PDFExportModule/PDFExportModule.em.arbeit.inc.php +++ b/api/v1/class/exports/modules/PDFExportModule/PDFExportModule.em.arbeit.inc.php @@ -86,7 +86,7 @@ public function export($args) $raw = @strftime("%d.%m.%Y", strtotime($row["schicht_tag"])); $rew = $row["schicht_anfang"]; $rol = $row["schicht_ende"]; - $ral = $row["ort"]; + $ral = $arbeit->i18n()->sanitizeOutput($row["ort"]); $rtn = $arbeit->type_from_int($row["Wtype"]) ?? "N/A"; $rps = @strftime("%H:%M", strtotime($row["pause_start"])); $rpe = @strftime("%H:%M", strtotime($row["pause_end"])); diff --git a/api/v1/class/mode/mode.arbeit.inc.php b/api/v1/class/mode/mode.arbeit.inc.php index 1bd29e8..706b456 100644 --- a/api/v1/class/mode/mode.arbeit.inc.php +++ b/api/v1/class/mode/mode.arbeit.inc.php @@ -28,7 +28,6 @@ public static function compute_html_worktime_types() if((int)$type == Arbeitszeit::get_app_ini()["config"]["default_worktime_type"]) { $selected = " selected"; } - print_r($type); $data .= ""; } return $data; diff --git a/api/v1/class/notifications/notifications.arbeit.inc.php b/api/v1/class/notifications/notifications.arbeit.inc.php index 906d515..d381fd6 100644 --- a/api/v1/class/notifications/notifications.arbeit.inc.php +++ b/api/v1/class/notifications/notifications.arbeit.inc.php @@ -118,10 +118,10 @@ public function get_notifications_html(){ $html = null; if($res->rowCount() > 0){ while($row = $res->fetch(\PDO::FETCH_ASSOC)){ - $location = $row["ort"]; + $location = $this->i18n()->sanitizeOutput($row["ort"]); $date = @strftime("%d.%m.%Y", strtotime($row["datum"])); $time = $row["uhrzeit"]; - $note = $row["notiz"]; + $note = $this->i18n()->sanitizeOutput($row["notiz"]); $id = $row["id"]; $html = <<< DATA diff --git a/composer.json b/composer.json index 41bccd5..7b20215 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "TimeTrack is a PHP-written time recording tool for small businesses", "type": "software", "license": "GNU GPL", - "version": "8.7", + "version": "8.7.1", "authors": [ { "name": "Bryan Boehnke-Avan", diff --git a/suite/actions/auth/login.php b/suite/actions/auth/login.php index 9423490..3a62b61 100644 --- a/suite/actions/auth/login.php +++ b/suite/actions/auth/login.php @@ -3,7 +3,7 @@ use Arbeitszeit\Auth; $auth = new Auth(); -$auth->login($_POST["username"], $_POST["password"], $option = ["erinnern" => $_POST["erinnern"]]); +$auth->login($_POST["username"], $_POST["password"], $option = ["erinnern" => $_POST["erinnern"] ?? false]); diff --git a/update.sh b/update.sh index 3798d8a..adce286 100644 --- a/update.sh +++ b/update.sh @@ -42,6 +42,7 @@ log "Updating folder permissions..." sudo chown -R www-data:www-data "$SCRIPT_DIR/data" || abort "Failed to set owner for /data" sudo chown -R www-data:www-data "$SCRIPT_DIR/api/v1/class/plugins/plugins" sudo chown www-data:www-data "$SCRIPT_DIR/api/v1/toil/permissions.json" +sudo chmod -R www-data:www-data "$SCRIPT_DIR" || abort "Failed to set permissions for TimeTrack root directory" log "Permissions updated." log "Update done successfully"