Merge pull request #315 from Focuslinkstech/Development

Fight Against Insecurity Ongoing
This commit is contained in:
iBNu Maksum 2024-10-10 21:44:40 +07:00 committed by GitHub
commit 6458b792f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 63 additions and 14 deletions

View File

@ -177,6 +177,7 @@ CREATE TABLE `tbl_users` (
`user_type` enum('SuperAdmin','Admin','Report','Agent','Sales') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `user_type` enum('SuperAdmin','Admin','Report','Agent','Sales') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`status` enum('Active','Inactive') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'Active', `status` enum('Active','Inactive') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'Active',
`last_login` datetime DEFAULT NULL, `last_login` datetime DEFAULT NULL,
`login_token` VARCHAR(255),
`creationdate` datetime NOT NULL `creationdate` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

@ -21,6 +21,15 @@ class Admin
if ($enable_session_timeout) { if ($enable_session_timeout) {
$_SESSION['aid_expiration'] = time() + $session_timeout_duration; $_SESSION['aid_expiration'] = time() + $session_timeout_duration;
} }
// Validate the token in the cookie
$isValid = self::validateToken($_SESSION['aid'], $_COOKIE['aid']);
if (!$isValid) {
self::removeCookie();
session_destroy();
_alert(Lang::T('Token has expired. Please log in again.'), 'danger', "admin");
return 0;
}
return $_SESSION['aid']; return $_SESSION['aid'];
} }
// Session expired, log out the user // Session expired, log out the user
@ -35,7 +44,15 @@ class Admin
// Check if the cookie is set and valid // Check if the cookie is set and valid
elseif (isset($_COOKIE['aid'])) { elseif (isset($_COOKIE['aid'])) {
$tmp = explode('.', $_COOKIE['aid']); $tmp = explode('.', $_COOKIE['aid']);
if (sha1($tmp[0] . '.' . $tmp[1] . '.' . $db_pass) == $tmp[2]) { if (sha1("$tmp[0].$tmp[1].$db_pass") == $tmp[2]) {
// Validate the token in the cookie
$isValid = self::validateToken($tmp[0], $_COOKIE['aid']);
if (!$isValid) {
self::removeCookie();
_alert(Lang::T('Token has expired. Please log in again.'), 'danger', "admin");
return 0;
}
if (time() - $tmp[1] < 86400 * 7) { if (time() - $tmp[1] < 86400 * 7) {
$_SESSION['aid'] = $tmp[0]; $_SESSION['aid'] = $tmp[0];
if ($enable_session_timeout) { if ($enable_session_timeout) {
@ -48,10 +65,9 @@ class Admin
return 0; return 0;
} }
public static function setCookie($aid) public static function setCookie($aid)
{ {
global $db_pass, $config; global $db_pass, $config, $_app_stage;
$enable_session_timeout = $config['enable_session_timeout']; $enable_session_timeout = $config['enable_session_timeout'];
$session_timeout_duration = intval($config['session_timeout_duration']) * 60; // Convert minutes to seconds $session_timeout_duration = intval($config['session_timeout_duration']) * 60; // Convert minutes to seconds
@ -61,12 +77,13 @@ class Admin
// Detect the current protocol // Detect the current protocol
$isSecure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; $isSecure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
$serverHost = $_SERVER['HTTP_HOST'];
$app_stage = ($serverHost === 'localhost') ? '' : APP_URL;
// Set cookie with security flags // Set cookie with security flags
setcookie('aid', $token, [ setcookie('aid', $token, [
'expires' => time() + 86400 * 7, // 7 days 'expires' => time() + 86400 * 7, // 7 days
'path' => '/', 'path' => '/',
'domain' => APP_URL, 'domain' => $app_stage,
'secure' => $isSecure, 'secure' => $isSecure,
'httponly' => true, 'httponly' => true,
'samesite' => 'Lax', // or Strict 'samesite' => 'Lax', // or Strict
@ -78,20 +95,25 @@ class Admin
$_SESSION['aid_expiration'] = $time + $session_timeout_duration; $_SESSION['aid_expiration'] = $time + $session_timeout_duration;
} }
self::upsertToken($aid, $token);
return $token; return $token;
} }
return ''; return '';
} }
public static function removeCookie() public static function removeCookie()
{ {
global $_app_stage;
if (isset($_COOKIE['aid'])) { if (isset($_COOKIE['aid'])) {
$isSecure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; $isSecure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
$serverHost = $_SERVER['HTTP_HOST'];
$app_stage = ($serverHost === 'localhost') ? '' : APP_URL;
setcookie('aid', '', [ setcookie('aid', '', [
'expires' => time() - 3600, 'expires' => time() - 3600,
'path' => '/', 'path' => '/',
'domain' => APP_URL, 'domain' => $app_stage,
'secure' => $isSecure, 'secure' => $isSecure,
'httponly' => true, 'httponly' => true,
'samesite' => 'Lax', 'samesite' => 'Lax',
@ -112,4 +134,27 @@ class Admin
return null; return null;
} }
} }
public static function upsertToken($aid, $token)
{
$query = ORM::for_table('tbl_users')->where('id', $aid)->findOne();
$query->login_token = $token;
$query->save();
}
public static function validateToken($aid, $cookieToken)
{
$query = ORM::for_table('tbl_users')->where('id', $aid)->findOne();
$storedToken = $query->login_token;
if (empty($storedToken)) {
return false;
}
if ($storedToken !== $cookieToken) {
return false;
}
return $storedToken === $cookieToken;
}
} }

View File

@ -15,7 +15,7 @@ switch ($action) {
$ui->assign('_system_menu', 'voucher'); $ui->assign('_system_menu', 'voucher');
$ui->assign('_title', Lang::T('Order Voucher')); $ui->assign('_title', Lang::T('Order Voucher'));
run_hook('customer_view_order'); #HOOK run_hook('customer_view_order'); #HOOK
$ui->display('user-ui/order.tpl'); $ui->display('customer/order.tpl');
break; break;
case 'history': case 'history':
$ui->assign('_system_menu', 'history'); $ui->assign('_system_menu', 'history');
@ -24,7 +24,7 @@ switch ($action) {
$ui->assign('d', $d); $ui->assign('d', $d);
$ui->assign('_title', Lang::T('Order History')); $ui->assign('_title', Lang::T('Order History'));
run_hook('customer_view_order_history'); #HOOK run_hook('customer_view_order_history'); #HOOK
$ui->display('user-ui/orderHistory.tpl'); $ui->display('customer/orderHistory.tpl');
break; break;
case 'balance': case 'balance':
if (strpos($user['email'], '@') === false) { if (strpos($user['email'], '@') === false) {
@ -34,7 +34,7 @@ switch ($action) {
$ui->assign('_system_menu', 'balance'); $ui->assign('_system_menu', 'balance');
$plans_balance = ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->where('prepaid', 'yes')->find_many(); $plans_balance = ORM::for_table('tbl_plans')->where('enabled', '1')->where('type', 'Balance')->where('prepaid', 'yes')->find_many();
$ui->assign('plans_balance', $plans_balance); $ui->assign('plans_balance', $plans_balance);
$ui->display('user-ui/orderBalance.tpl'); $ui->display('customer/orderBalance.tpl');
break; break;
case 'package': case 'package':
if (strpos($user['email'], '@') === false) { if (strpos($user['email'], '@') === false) {
@ -127,7 +127,7 @@ switch ($action) {
$ui->assign('plans_hotspot', $plans_hotspot); $ui->assign('plans_hotspot', $plans_hotspot);
$ui->assign('plans_vpn', $plans_vpn); $ui->assign('plans_vpn', $plans_vpn);
run_hook('customer_view_order_plan'); #HOOK run_hook('customer_view_order_plan'); #HOOK
$ui->display('user-ui/orderPlan.tpl'); $ui->display('customer/orderPlan.tpl');
break; break;
case 'unpaid': case 'unpaid':
$d = ORM::for_table('tbl_payment_gateway') $d = ORM::for_table('tbl_payment_gateway')
@ -192,7 +192,7 @@ switch ($action) {
$ui->assign('plan', $plan); $ui->assign('plan', $plan);
$ui->assign('bandw', $bandw); $ui->assign('bandw', $bandw);
$ui->assign('_title', 'TRX #' . $trxid); $ui->assign('_title', 'TRX #' . $trxid);
$ui->display('user-ui/orderView.tpl'); $ui->display('customer/orderView.tpl');
break; break;
case 'pay': case 'pay':
if ($config['enable_balance'] != 'yes') { if ($config['enable_balance'] != 'yes') {
@ -383,7 +383,7 @@ switch ($action) {
$ui->assign('router', $router_name); $ui->assign('router', $router_name);
$ui->assign('plan', $plan); $ui->assign('plan', $plan);
$ui->assign('tax', $tax); $ui->assign('tax', $tax);
$ui->display('user-ui/sendPlan.tpl'); $ui->display('customer/sendPlan.tpl');
break; break;
case 'gateway': case 'gateway':
$ui->assign('_title', Lang::T('Select Payment Gateway')); $ui->assign('_title', Lang::T('Select Payment Gateway'));
@ -421,7 +421,7 @@ switch ($action) {
$ui->assign('add_cost', $add_cost); $ui->assign('add_cost', $add_cost);
$ui->assign('bills', $bills); $ui->assign('bills', $bills);
$ui->assign('plan', $plan); $ui->assign('plan', $plan);
$ui->display('user-ui/selectGateway.tpl'); $ui->display('customer/selectGateway.tpl');
break; break;
} else { } else {
sendTelegram("Payment Gateway not set, please set it in Settings"); sendTelegram("Payment Gateway not set, please set it in Settings");

View File

@ -161,5 +161,8 @@
"ALTER TABLE `tbl_customers` CHANGE `service_type` `service_type` ENUM('Hotspot','PPPoE','VPN','Others') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'Others' COMMENT 'For selecting user type';", "ALTER TABLE `tbl_customers` CHANGE `service_type` `service_type` ENUM('Hotspot','PPPoE','VPN','Others') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'Others' COMMENT 'For selecting user type';",
"ALTER TABLE `tbl_transactions` CHANGE `type` `type` ENUM('Hotspot','PPPOE','VPN','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;", "ALTER TABLE `tbl_transactions` CHANGE `type` `type` ENUM('Hotspot','PPPOE','VPN','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;",
"CREATE TABLE IF NOT EXISTS `tbl_port_pool` ( `id` int(10) NOT NULL AUTO_INCREMENT , `public_ip` varchar(40) NOT NULL, `port_name` varchar(40) NOT NULL, `range_port` varchar(40) NOT NULL, `routers` varchar(40) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;" "CREATE TABLE IF NOT EXISTS `tbl_port_pool` ( `id` int(10) NOT NULL AUTO_INCREMENT , `public_ip` varchar(40) NOT NULL, `port_name` varchar(40) NOT NULL, `range_port` varchar(40) NOT NULL, `routers` varchar(40) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;"
],
"2024.10.10": [
"ALTER TABLE `tbl_users` ADD `login_token` VARCHAR(255) AFTER `last_login`;"
] ]
} }