diff --git a/GameEngine/Database/DatabaseArtefactQueries.php b/GameEngine/Database/DatabaseArtefactQueries.php index 9a38ac79..0b9f5e1e 100644 --- a/GameEngine/Database/DatabaseArtefactQueries.php +++ b/GameEngine/Database/DatabaseArtefactQueries.php @@ -439,6 +439,11 @@ trait DatabaseArtefactQueries { */ function getInactiveArtifacts($time){ + // Identificatorii intra in SQL fara ghilimele, iar + // mysqli_real_escape_string nu protejeaza contextul numeric: + // "5 OR 1=1" ar trece neschimbat. Conversia la intreg il opreste. + $time = (int) $time; + list($time) = $this->escape_input($time); $q = "SELECT * FROM ".TB_PREFIX."artefacts WHERE active = 0 AND owner > 5 AND conquered <= $time AND del = 0 ORDER BY conquered ASC, size ASC"; diff --git a/GameEngine/Database/DatabaseMarketQueries.php b/GameEngine/Database/DatabaseMarketQueries.php index 39f8b4d8..175af1ef 100644 --- a/GameEngine/Database/DatabaseMarketQueries.php +++ b/GameEngine/Database/DatabaseMarketQueries.php @@ -207,6 +207,12 @@ trait DatabaseMarketQueries { ***************************/ function getMarketField($vref, $id, $field, $use_cache = true) { + // Identificatorii intra in SQL fara ghilimele, iar + // mysqli_real_escape_string nu protejeaza contextul numeric: + // "5 OR 1=1" ar trece neschimbat. Conversia la intreg il opreste. + $vref = (int) $vref; + $id = (int) $id; + list($vref, $id, $field) = $this->escape_input($vref, $id, $field); // first of all, check if we should be using cache and whether the field diff --git a/GameEngine/Database/DatabaseMessageQueries.php b/GameEngine/Database/DatabaseMessageQueries.php index 1d63fe07..fad918be 100644 --- a/GameEngine/Database/DatabaseMessageQueries.php +++ b/GameEngine/Database/DatabaseMessageQueries.php @@ -76,29 +76,75 @@ trait DatabaseMessageQueries { } } - function setArchived($id) { - if (!is_array($id)) { - $id = [$id]; + function setArchived($id, $uid) { + /** + * FIX SECURITATE (IDOR): identificatorii vin din formular, deci pot fi + * ai altui jucator. Fara conditia de proprietar, oricine putea sterge + * sau arhiva rapoartele si mesajele oricui, doar ghicind ID-uri - ele + * sunt secventiale si usor de enumerat. + * + * Acelasi tipar exista deja in removeMessage() si getReadNotice(); + * aceste cinci actiuni fusesera uitate. + * + * Conditia sta in SQL, nu in apelant: asa protejeaza ORICE apelant. + */ + $uid = (int) $uid; - foreach ($id as $index => $idValue) { - $id[$index] = (int) $idValue; - } + if ($uid <= 0) { + return false; } - $q = "UPDATE " . TB_PREFIX . "mdata set archived = 1 where id IN(".implode(', ', $id).")"; + if (!is_array($id)) { + $id = [$id]; + } + + // Conversia se aplica acum si array-urilor. Inainte statea in ramura + // "nu e array", deci pe cazul obisnuit nu rula niciodata. + $id = array_values(array_filter(array_map('intval', $id), function ($v) { + return $v > 0; + })); + + if (!$id) { + return false; + } + + $q = "UPDATE " . TB_PREFIX . "mdata set archived = 1 WHERE id IN(" . implode(',', $id) . ") AND (target = $uid OR owner = $uid)"; return mysqli_query($this->dblink,$q); } - function setNorm($id) { - if (!is_array($id)) { - $id = [$id]; + function setNorm($id, $uid) { + /** + * FIX SECURITATE (IDOR): identificatorii vin din formular, deci pot fi + * ai altui jucator. Fara conditia de proprietar, oricine putea sterge + * sau arhiva rapoartele si mesajele oricui, doar ghicind ID-uri - ele + * sunt secventiale si usor de enumerat. + * + * Acelasi tipar exista deja in removeMessage() si getReadNotice(); + * aceste cinci actiuni fusesera uitate. + * + * Conditia sta in SQL, nu in apelant: asa protejeaza ORICE apelant. + */ + $uid = (int) $uid; - foreach ($id as $index => $idValue) { - $id[$index] = (int) $idValue; - } + if ($uid <= 0) { + return false; } - $q = "UPDATE " . TB_PREFIX . "mdata set archived = 0 where id IN(".implode(',', $id).")"; + if (!is_array($id)) { + $id = [$id]; + } + + // Conversia se aplica acum si array-urilor. Inainte statea in ramura + // "nu e array", deci pe cazul obisnuit nu rula niciodata. + $id = array_values(array_filter(array_map('intval', $id), function ($v) { + return $v > 0; + })); + + if (!$id) { + return false; + } + + $q = "UPDATE " . TB_PREFIX . "mdata set archived = 0 WHERE id IN(" . implode(',', $id) . ") AND (target = $uid OR owner = $uid)"; return mysqli_query($this->dblink,$q); } @@ -198,42 +244,111 @@ References: User ID/Message ID, Mode else return mysqli_query($this->dblink,$q); } - function unarchiveNotice($id) { - if (!is_array($id)) { - $id = [$id]; + function unarchiveNotice($id, $uid) { + /** + * FIX SECURITATE (IDOR): identificatorii vin din formular, deci pot fi + * ai altui jucator. Fara conditia de proprietar, oricine putea sterge + * sau arhiva rapoartele si mesajele oricui, doar ghicind ID-uri - ele + * sunt secventiale si usor de enumerat. + * + * Acelasi tipar exista deja in removeMessage() si getReadNotice(); + * aceste cinci actiuni fusesera uitate. + * + * Conditia sta in SQL, nu in apelant: asa protejeaza ORICE apelant. + */ + $uid = (int) $uid; - foreach ($id as $index => $idValue) { - $id[$index] = (int) $idValue; - } + if ($uid <= 0) { + return false; } - $q = "UPDATE " . TB_PREFIX . "ndata set ntype = archive, archive = 0 where id IN(".implode(',', $id).")"; + if (!is_array($id)) { + $id = [$id]; + } + + // Conversia se aplica acum si array-urilor. Inainte statea in ramura + // "nu e array", deci pe cazul obisnuit nu rula niciodata. + $id = array_values(array_filter(array_map('intval', $id), function ($v) { + return $v > 0; + })); + + if (!$id) { + return false; + } + + $q = "UPDATE " . TB_PREFIX . "ndata set ntype = archive, archive = 0 WHERE id IN(" . implode(',', $id) . ") AND uid = $uid"; return mysqli_query($this->dblink,$q); } - function archiveNotice($id) { - if (!is_array($id)) { - $id = [$id]; + function archiveNotice($id, $uid) { + /** + * FIX SECURITATE (IDOR): identificatorii vin din formular, deci pot fi + * ai altui jucator. Fara conditia de proprietar, oricine putea sterge + * sau arhiva rapoartele si mesajele oricui, doar ghicind ID-uri - ele + * sunt secventiale si usor de enumerat. + * + * Acelasi tipar exista deja in removeMessage() si getReadNotice(); + * aceste cinci actiuni fusesera uitate. + * + * Conditia sta in SQL, nu in apelant: asa protejeaza ORICE apelant. + */ + $uid = (int) $uid; - foreach ($id as $index => $idValue) { - $id[$index] = (int) $idValue; - } + if ($uid <= 0) { + return false; } - $q = "update " . TB_PREFIX . "ndata set archive = ntype, ntype = 9 where id IN(".implode(',', $id).")"; + if (!is_array($id)) { + $id = [$id]; + } + + // Conversia se aplica acum si array-urilor. Inainte statea in ramura + // "nu e array", deci pe cazul obisnuit nu rula niciodata. + $id = array_values(array_filter(array_map('intval', $id), function ($v) { + return $v > 0; + })); + + if (!$id) { + return false; + } + + $q = "UPDATE " . TB_PREFIX . "ndata set archive = ntype, ntype = 9 WHERE id IN(" . implode(',', $id) . ") AND uid = $uid"; return mysqli_query($this->dblink,$q); } - function removeNotice($id) { - if (!is_array($id)) { - $id = [$id]; + function removeNotice($id, $uid) { + /** + * FIX SECURITATE (IDOR): identificatorii vin din formular, deci pot fi + * ai altui jucator. Fara conditia de proprietar, oricine putea sterge + * sau arhiva rapoartele si mesajele oricui, doar ghicind ID-uri - ele + * sunt secventiale si usor de enumerat. + * + * Acelasi tipar exista deja in removeMessage() si getReadNotice(); + * aceste cinci actiuni fusesera uitate. + * + * Conditia sta in SQL, nu in apelant: asa protejeaza ORICE apelant. + */ + $uid = (int) $uid; - foreach ($id as $index => $idValue) { - $id[$index] = (int) $idValue; - } + if ($uid <= 0) { + return false; } - $q = "UPDATE " . TB_PREFIX . "ndata set del = 1,viewed = 1 where id IN(".implode(',', $id).")"; + if (!is_array($id)) { + $id = [$id]; + } + + // Conversia se aplica acum si array-urilor. Inainte statea in ramura + // "nu e array", deci pe cazul obisnuit nu rula niciodata. + $id = array_values(array_filter(array_map('intval', $id), function ($v) { + return $v > 0; + })); + + if (!$id) { + return false; + } + + $q = "UPDATE " . TB_PREFIX . "ndata set del = 1, viewed = 1 WHERE id IN(" . implode(',', $id) . ") AND uid = $uid"; return mysqli_query($this->dblink,$q); } diff --git a/GameEngine/Database/DatabaseMovementQueries.php b/GameEngine/Database/DatabaseMovementQueries.php index 0ef4149b..6a700d06 100644 --- a/GameEngine/Database/DatabaseMovementQueries.php +++ b/GameEngine/Database/DatabaseMovementQueries.php @@ -24,6 +24,20 @@ trait DatabaseMovementQueries { function setMovementProc($moveid) { + // $moveid poate fi UN identificator sau o LISTA separata prin virgula + // (vezi DatabaseVillageQueries, care trimite implode(', ', $moveIDs)), + // asa ca o simpla conversie la intreg ar rupe cazul cu lista. + // + // Filtram fiecare element in parte: raman doar numere, restul dispare. + // Asa "5 OR 1=1" nu mai poate ajunge in SQL. + $moveIds = array_filter(array_map('intval', explode(',', (string) $moveid))); + + if (!$moveIds) { + return false; + } + + $moveid = implode(', ', $moveIds); + if (!Math::isInt($moveid)) { list($moveid) = $this->escape_input($moveid); } diff --git a/GameEngine/Database/DatabaseVillageQueries.php b/GameEngine/Database/DatabaseVillageQueries.php index c6327209..1163e1ae 100644 --- a/GameEngine/Database/DatabaseVillageQueries.php +++ b/GameEngine/Database/DatabaseVillageQueries.php @@ -2208,6 +2208,11 @@ trait DatabaseVillageQueries { } function getCropProdstarv($wref, $use_cache = true) { + // Identificatorii intra in SQL fara ghilimele, iar + // mysqli_real_escape_string nu protejeaza contextul numeric: + // "5 OR 1=1" ar trece neschimbat. Conversia la intreg il opreste. + $wref = (int) $wref; + global $bid4, $bid8, $bid9, $technology; // first of all, check if we should be using cache and whether the field diff --git a/GameEngine/Message.php b/GameEngine/Message.php index b27c7059..3db992ca 100755 --- a/GameEngine/Message.php +++ b/GameEngine/Message.php @@ -372,45 +372,45 @@ class Message private function archiveMessage($post) { - global $database; + global $database, $session; $archIDs = $this->collectSelectedIds($post); - $database->setArchived($archIDs); + $database->setArchived($archIDs, (int) $session->uid); header("Location: nachrichten.php"); exit; } private function unarchiveMessage($post) { - global $database; + global $database, $session; $normIDs = $this->collectSelectedIds($post); - $database->setNorm($normIDs); + $database->setNorm($normIDs, (int) $session->uid); header("Location: nachrichten.php"); exit; } private function removeNotice($post) { - global $database; + global $database, $session; $removeIDs = $this->collectSelectedIds($post); - $database->removeNotice($removeIDs); + $database->removeNotice($removeIDs, (int) $session->uid); header("Location: berichte.php"); exit; } private function archiveNotice($post) { - global $database; + global $database, $session; $archiveIDs = $this->collectSelectedIds($post); - $database->archiveNotice($archiveIDs); + $database->archiveNotice($archiveIDs, (int) $session->uid); header("Location: berichte.php"); exit; } private function unarchiveNotice($post) { - global $database; + global $database, $session; $unarchIDs = $this->collectSelectedIds($post); - $database->unarchiveNotice($unarchIDs); + $database->unarchiveNotice($unarchIDs, (int) $session->uid); header("Location: berichte.php"); exit; }