File: /home/g/e/y/geyhairs/www/kvih6/guard.php
<?php
/**
* ============================================
* PAGE GUARD (guard.php)
* حارس الصفحات المحمية
* ============================================
*
* الاستخدام: حُط هذا السطر في أول كل صفحة بدك تحميها،
* قبل أي output (قبل أي HTML أو مسافات):
*
* <?php require_once __DIR__ . '/guard.php'; ?>
*
* شو بيعمل:
* - يفحص هل الزائر عنده جلسة موثّقة (مرّ من البوابة index.php ونجح)
* - يتأكد إن الجلسة ما انتهت، وإن الـ IP/UA ما تغيّروا (منع سرقة الجلسة)
* - لو كل شي تمام → الصفحة بتكمل تشتغل عادي
* - لو لأ → بيطرده ويرجّعه للبوابة
*
* مهم: لازم تكون نفس إعدادات الجلسة بين index.php و guard.php،
* عشان هيك حطّينا نفس session_name و session params بالملفين.
*/
// ============================================
// إعدادات الجلسة - لازم تطابق index.php بالظبط
// ============================================
const GATEWAY_URL = 'index.php'; // البوابة - لو الزائر مش موثّق بيتحوّل لهون
// نفس اسم الجلسة المستخدم في البوابة (افتراضي PHP لو ما غيّرته)
// لو غيّرت session_name في index.php، غيّره هون لنفس القيمة.
// إعدادات أمان للكوكي (تطابق ما هو موصى به في البوابة)
if (session_status() === PHP_SESSION_NONE) {
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'httponly' => true,
'samesite' => 'Lax',
// 'secure' => true, // فعّلها لما يصير الموقع HTTPS (مفروض يكون)
]);
session_start();
}
// ============================================
// دالة الطرد
// ============================================
function guard_reject(string $reason): void
{
// (اختياري) سجّل المحاولة لو ملف اللوج موجود
$logFile = __DIR__ . '/logs/security.log';
if (is_dir(dirname($logFile))) {
$ip = guard_get_ip();
$entry = json_encode([
'time' => date('c'),
'event' => 'guard_blocked',
'data' => [
'reason' => $reason,
'ip' => $ip,
'page' => $_SERVER['REQUEST_URI'] ?? '',
'ua' => substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 150),
],
], JSON_UNESCAPED_UNICODE) . "\n";
@file_put_contents($logFile, $entry, FILE_APPEND | LOCK_EX);
}
// امسح أي جلسة فاسدة
$_SESSION = [];
// حوّل للبوابة (مش بنعرض صفحة خطأ - بنرجّعه يحاول من الأول)
if (!headers_sent()) {
header('Location: ' . GATEWAY_URL, true, 302);
} else {
// احتياط لو الـ headers انبعتت (output طلع قبل الحارس)
echo '<script>window.location.replace(' . json_encode(GATEWAY_URL) . ');</script>';
}
exit;
}
// ============================================
// دوال مساعدة (تطابق منطق البوابة)
// ============================================
function guard_get_ip(): string
{
foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'] as $key) {
if (!empty($_SERVER[$key])) {
$ip = trim(explode(',', $_SERVER[$key])[0]);
if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
}
}
return '0.0.0.0';
}
// ============================================
// الفحص الأساسي
// ============================================
// 1) في جلسة موثّقة أصلاً؟
if (!isset($_SESSION['verified']) || !is_array($_SESSION['verified'])) {
guard_reject('no_verified_session');
}
$v = $_SESSION['verified'];
// 2) الجلسة فيها كل الحقول المطلوبة؟
if (empty($v['token']) || empty($v['expires']) || empty($v['ip']) || empty($v['ua_hash'])) {
guard_reject('malformed_session');
}
// 3) الجلسة انتهت؟
if ($v['expires'] < time()) {
guard_reject('session_expired');
}
// 4) الـ IP تغيّر؟ (منع استخدام نفس الكوكي من جهاز ثاني)
$currentIP = guard_get_ip();
if ($v['ip'] !== $currentIP) {
guard_reject('ip_changed');
}
// 5) الـ User-Agent تغيّر؟ (إشارة سرقة جلسة)
$currentUAHash = md5($_SERVER['HTTP_USER_AGENT'] ?? '');
if ($v['ua_hash'] !== $currentUAHash) {
guard_reject('ua_changed');
}
// ============================================
// نجح كل الفحوصات - الزائر موثّق
// ============================================
// (اختياري) تمديد الجلسة مع كل صفحة عشان ما تنتهي والزائر نشط
// إذا ما بدك تمديد، احذف السطر التالي.
$_SESSION['verified']['expires'] = time() + 3600;
// خلاص - الصفحة اللي عملت include بتكمل تشتغل عادي من هون