Selamlar,

Bir intranet sistemim var ve bu intranet sistemine kullanıcılar AD ile senkron olarak giriş yapıyor.

Giriş yaptıktan sonra bazı bölümlere ait yönetim panelleri var ve bu panellere menü üzerinden ulaşılıyor, şuan local bir db üzerinde tutulan kullanıcı bilgileri ile giriş yapıyorlar ve güvenilir olduğunu düşünmüyorum.

Tasarladığım yapıda AD üzerinde gruplar oluşturdum ve eğer intranet sistemine giren kullanıcı bu gruba üye ise bu ekrana girebilecek fakat değilse geri yönlenecek. Bu alanlar önemli alanlar (duyuru paneli gibi) olduğu için güvenliği üst düzeyde tutmak istiyorum.

Yapay zekadan yardım alarak yapmış olduğum ve tasarladığım giriş sistemi aşağıdaki gibidir, önerileriniz var mıdır?

Güvenlik açısından girmiş olduğu panel üzerindeki her sayfada bu kontrolü yine yaptıracağım.

<?php
    ini_set('session.use_strict_mode', 1);
    
    ini_set('session.cookie_httponly', 1);
    ini_set('session.cookie_secure', 1);
    ini_set('session.cookie_samesite', 'Strict');
        
    error_reporting(0);
    ini_set('display_errors', 0);
    function logError($message) {
        error_log("[" . date("Y-m-d H:i:s") . "] " . $message . "\n", 3, "/var/www/cloud.domain.com.tr/islemler/testpanel/process.log");
    }
    function secureExit($message = '') {
        session_destroy();
        if (!empty($message)) {
            logError($message);
        }
        header('Location: ../../login.php');
        exit();
    }
    try {
        if (session_status() == PHP_SESSION_NONE) {
            session_start();
        }
        
        if (!isset($_SESSION['initialized']) || !$_SESSION['initialized']) {
            session_regenerate_id(true);
            $_SESSION['initialized'] = true;
            $_SESSION['client_ip'] = $_SERVER['REMOTE_ADDR'];
            $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
            $_SESSION['last_activity'] = time();
        }
        
        if ($_SESSION['client_ip'] !== $_SERVER['REMOTE_ADDR'] || 
            $_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
            logError("Olası session hijacking denemesi tespit edildi.");
            secureExit('Güvenlik ihlali tespit edildi.');
        }
        $ldap_config = [
            'host' => 'IP',
            'base_dn' => 'DN',
            'username' => 'USER',
            'password' => 'PW',
            'required_group' => 'CN'
        ];
        if (!isset($_SESSION['username']) || empty($_SESSION['username'])) {
            logError("Username session bulunamadı.");
            secureExit('Oturum bulunamadı.');
        }
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!isset($_SESSION['csrf_token']) || !isset($_POST['csrf_token']) || 
                $_SESSION['csrf_token'] !== $_POST['csrf_token']) {
                logError("CSRF token doğrulaması başarısız: " . $_SESSION['username']);
                secureExit('CSRF token doğrulaması başarısız.');
            }
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
        function verifyGroupMembership($username, $config) {
            $ldap_conn = ldap_connect($config['host']);
            if (!$ldap_conn) {
                throw new Exception('LDAP sunucusuna bağlanılamadı.');
            }
            ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
            ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, 0);
            ldap_set_option($ldap_conn, LDAP_OPT_NETWORK_TIMEOUT, 5);
            if (!ldap_bind($ldap_conn, $config['username'], $config['password'])) {
                throw new Exception('LDAP kimlik doğrulaması başarısız.');
            }
            $filter = "(sAMAccountName=" . ldap_escape($username, "", LDAP_ESCAPE_FILTER) . ")";
            $search = ldap_search($ldap_conn, $config['base_dn'], $filter, ['dn']);
            
            if (!$search || ldap_count_entries($ldap_conn, $search) !== 1) {
                throw new Exception('Kullanıcı bulunamadı veya birden fazla sonuç döndü.');
            }
            $user_entry = ldap_first_entry($ldap_conn, $search);
            $user_dn = ldap_get_dn($ldap_conn, $user_entry);
            $group_filter = "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=$user_dn))";
            $group_search = ldap_search($ldap_conn, $config['base_dn'], $group_filter, ['dn']);
            
            $entries = ldap_get_entries($ldap_conn, $group_search);
            $has_access = false;
            for ($i = 0; $i < $entries["count"]; $i++) {
                if (strcasecmp($entries[$i]["dn"], $config['required_group']) === 0) {
                    $has_access = true;
                    break;
                }
            }
            ldap_close($ldap_conn);
            return $has_access;
        }
        if (!verifyGroupMembership($_SESSION['username'], $ldap_config)) {
            logError("Yetkisiz erişim denemesi: " . $_SESSION['username']);
            header("Location: https://cloud.domain.com.tr");
            exit();
        } else {
            logError("Kullanıcı girişi başarılı: " . $_SESSION['username']);
        }
        $allowed_session_keys = [
            'name', 'surname', 'unvan', 'username', 'mail', 
            'telephonenumber', 'comment', 'company', 'department', 
            'mobile', 'physicaldeliveryofficename'
        ];
        foreach ($allowed_session_keys as $key) {
            $$key = isset($_SESSION[$key]) ? htmlspecialchars($_SESSION[$key], ENT_QUOTES, 'UTF-8') : '';
        }
        if (!isset($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
    } catch (Exception $e) {
        logError($e->getMessage());
        secureExit();
    }
?>