Important security fix

Important security fix
This commit is contained in:
novgorodschi catalin
2026-08-05 10:39:38 +03:00
parent 94f5593f22
commit ae2d835a84
5 changed files with 40 additions and 10 deletions
+1 -1
View File
@@ -294,7 +294,7 @@ class Building {
$validChecker = ( $validChecker = (
isset($get['c']) && isset($get['c']) &&
$get['c'] == $this->sess->checker hash_equals((string) $this->sess->checker, (string) ($get['c'] ?? ''))
); );
// REMOVE / UPGRADE EXISTING // REMOVE / UPGRADE EXISTING
+1 -1
View File
@@ -98,7 +98,7 @@ class Market
if ( if (
isset($get['t'], $get['a']) && isset($get['t'], $get['a']) &&
$get['t'] == 1 && $get['t'] == 1 &&
$get['a'] == $session->mchecker && hash_equals((string) $session->mchecker, (string) ($get['a'] ?? '')) &&
!isset($get['del']) !isset($get['del'])
) { ) {
$session->changeChecker(); $session->changeChecker();
+2 -2
View File
@@ -469,7 +469,7 @@ class Profile {
exit; exit;
} }
if ($get['a'] == $session->checker) { if (hash_equals((string) $session->checker, (string) ($get['a'] ?? ''))) {
if ($session->userinfo['sit' . $type] == $get['id']) { if ($session->userinfo['sit' . $type] == $get['id']) {
$database->updateUserField($session->uid, "sit" . $type, 0, 1); $database->updateUserField($session->uid, "sit" . $type, 0, 1);
@@ -503,7 +503,7 @@ class Profile {
private function removeMeSit($get) { private function removeMeSit($get) {
global $database, $session; global $database, $session;
if ($get['a'] == $session->checker) { if (hash_equals((string) $session->checker, (string) ($get['a'] ?? ''))) {
$database->removeMeSit($get['id'], $session->uid); $database->removeMeSit($get['id'], $session->uid);
$session->changeChecker(); $session->changeChecker();
} }
+34 -4
View File
@@ -101,6 +101,25 @@ function __construct() {
$this->time = time(); $this->time = time();
if (!isset($_SESSION)) { if (!isset($_SESSION)) {
/**
* FIX SECURITATE (CSRF): cookie-ul de sesiune nu avea SameSite, deci
* era trimis si la cereri pornite de pe alte site-uri. Panoul de admin
* avea deja 'Strict' (vezi Admin/admin.php); jocul, nu.
*
* Folosim 'Lax', nu 'Strict': cu Strict, un jucator care intra pe link
* din forum sau dintr-un e-mail ar aparea delogat. Lax pastreaza
* navigarea normala si opreste cererile POST venite din alta parte.
*/
if (PHP_VERSION_ID >= 70300) {
session_set_cookie_params(array(
'lifetime' => 0,
'path' => '/',
'secure' => !empty($_SERVER['HTTPS']),
'httponly' => true,
'samesite' => 'Lax',
));
}
session_start(); session_start();
} }
@@ -170,8 +189,18 @@ function __construct() {
$user_sanitized = $database->escape($user); $user_sanitized = $database->escape($user);
$_SESSION['checker'] = $generator->generateRandStr(3); /**
$_SESSION['mchecker'] = $generator->generateRandStr(5); * FIX SECURITATE (CSRF): token-urile aveau 3 si 5 caractere.
*
* 3 caractere = 62^3 = 238.328 combinatii, adica se pot incerca toate
* in sub o ora, fara nicio limitare de rata. Cu 32 de caractere ajung
* la 62^32 - imposibil de ghicit.
*
* Generatorul folosea deja random_int(), care e sigur criptografic;
* problema era doar lungimea.
*/
$_SESSION['checker'] = $generator->generateRandStr(32);
$_SESSION['mchecker'] = $generator->generateRandStr(32);
$userFields = $database->getUserFields($user_sanitized, "quest, id", 1, true); $userFields = $database->getUserFields($user_sanitized, "quest, id", 1, true);
$_SESSION['qst'] = $userFields["quest"]; $_SESSION['qst'] = $userFields["quest"];
@@ -244,8 +273,9 @@ function __construct() {
public function changeChecker() { public function changeChecker() {
global $generator; global $generator;
$this->checker = $_SESSION['checker'] = $generator->generateRandStr(3); // 32 de caractere: vezi explicatia de la generarea initiala.
$this->mchecker = $_SESSION['mchecker'] = $generator->generateRandStr(5); $this->checker = $_SESSION['checker'] = $generator->generateRandStr(32);
$this->mchecker = $_SESSION['mchecker'] = $generator->generateRandStr(32);
} }
/** /**
+2 -2
View File
@@ -901,7 +901,7 @@ class Technology {
if (!$database->getResearchLock($village->wid)) return; if (!$database->getResearchLock($village->wid)) return;
try { try {
$village->researching = $database->getResearching($village->wid, false); $village->researching = $database->getResearching($village->wid, false);
if($this->meetRRequirement($get['a']) && $get['c'] == $session->mchecker) { if($this->meetRRequirement($get['a']) && hash_equals((string) $session->mchecker, (string) ($get['c'] ?? ''))) {
$data = ${'r'.$get['a']}; $data = ${'r'.$get['a']};
$time = time() + round(($data['time'] * ($bid22[$building->getTypeLevel(22)]['attri'] / 100))/SPEED); $time = time() + round(($data['time'] * ($bid22[$building->getTypeLevel(22)]['attri'] / 100))/SPEED);
$database->modifyResource($village->wid,$data['wood'],$data['clay'],$data['iron'],$data['crop'],0); $database->modifyResource($village->wid,$data['wood'],$data['clay'],$data['iron'],$data['crop'],0);
@@ -939,7 +939,7 @@ class Technology {
$CurrentTech = $ABTech[$type.$get['a']]+$ups; $CurrentTech = $ABTech[$type.$get['a']]+$ups;
$unit = ($session->tribe-1)*10+intval($get['a']); $unit = ($session->tribe-1)*10+intval($get['a']);
if(($ABUpgradesCount < 2 && $session->plus || $ABUpgradesCount == 0) && ($this->getTech($unit) || ($unit % 10) == 1) && ($CurrentTech < $building->getTypeLevel($buildingType)) && $get['c'] == $session->mchecker) { if(($ABUpgradesCount < 2 && $session->plus || $ABUpgradesCount == 0) && ($this->getTech($unit) || ($unit % 10) == 1) && ($CurrentTech < $building->getTypeLevel($buildingType)) && hash_equals((string) $session->mchecker, (string) ($get['c'] ?? ''))) {
global ${'ab'.strval($unit)}; global ${'ab'.strval($unit)};
$data = ${'ab'.strval($unit)}; $data = ${'ab'.strval($unit)};
$time = time() + round(($data[$CurrentTech+1]['time'] * ($bidBuilding[$building->getTypeLevel($buildingType)]['attri'] / 100))/SPEED) + ($ABUpgradesCount > 0 ? ($ABUpgrades[$ABUpgradesCount-1]['timestamp'] - time()) + ceil(60/SPEED) : 0); $time = time() + round(($data[$CurrentTech+1]['time'] * ($bidBuilding[$building->getTypeLevel($buildingType)]['attri'] / 100))/SPEED) + ($ABUpgradesCount > 0 ? ($ABUpgrades[$ABUpgradesCount-1]['timestamp'] - time()) + ceil(60/SPEED) : 0);