Protokoll #32951

ID32951
Zeitstempel2026-02-15 06:55:22.683587
Clientroot
IP145.224.72.253
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens3,573 (Input: 352, Output: 3,221)
Dauer99 ms
Request-Zeit2026-02-15 06:55:22.683587
Response-Zeit2026-02-15 06:55:22.782225

Request

{
    "event": "PreToolUse",
    "tool_name": "Edit",
    "tool_input": {
        "file_path": "\/tmp\/BotDetectionService-groupC.php",
        "old_string": "    public function unblockIp(string $ip): bool\n    {\n        \/\/ Remove from JSON file\n        if (file_exists($this->blockedIpsFile)) {\n            $blockedIps = json_decode(file_get_contents($this->blockedIpsFile), true) ?? [];\n            unset($blockedIps[$ip]);\n            file_put_contents($this->blockedIpsFile, json_encode($blockedIps, JSON_PRETTY_PRINT));\n        }\n        \n        \/\/ Remove UFW rule\n        try {\n            $ufwCmd = \"sudo ufw delete deny from $ip\";\n            shell_exec($ufwCmd . ' 2>&1');\n            $this->logger->info(\"UFW rule removed for IP: $ip\");\n            return true;\n        } catch (\\Exception $e) {\n            $this->logger->error(\"Failed to remove UFW rule for $ip: \" . $e->getMessage());\n            return false;\n        }\n    }",
        "new_string": "    public function unblockIp(string $ip): bool\n    {\n        if (file_exists($this->blockedIpsFile)) {\n            $blockedIps = json_decode(file_get_contents($this->blockedIpsFile), true) ?? [];\n            unset($blockedIps[$ip]);\n            file_put_contents($this->blockedIpsFile, json_encode($blockedIps, JSON_PRETTY_PRINT));\n        }\n\n        $this->logger->info(\"IP unblocked: $ip\");\n        return true;\n    }",
        "replace_all": false
    }
}

Response

{
    "tool_response": {
        "filePath": "\/tmp\/BotDetectionService-groupC.php",
        "oldString": "    public function unblockIp(string $ip): bool\n    {\n        \/\/ Remove from JSON file\n        if (file_exists($this->blockedIpsFile)) {\n            $blockedIps = json_decode(file_get_contents($this->blockedIpsFile), true) ?? [];\n            unset($blockedIps[$ip]);\n            file_put_contents($this->blockedIpsFile, json_encode($blockedIps, JSON_PRETTY_PRINT));\n        }\n        \n        \/\/ Remove UFW rule\n        try {\n            $ufwCmd = \"sudo ufw delete deny from $ip\";\n            shell_exec($ufwCmd . ' 2>&1');\n            $this->logger->info(\"UFW rule removed for IP: $ip\");\n            return true;\n        } catch (\\Exception $e) {\n            $this->logger->error(\"Failed to remove UFW rule for $ip: \" . $e->getMessage());\n            return false;\n        }\n    }",
        "newString": "    public function unblockIp(string $ip): bool\n    {\n        if (file_exists($this->blockedIpsFile)) {\n            $blockedIps = json_decode(file_get_contents($this->blockedIpsFile), true) ?? [];\n            unset($blockedIps[$ip]);\n            file_put_contents($this->blockedIpsFile, json_encode($blockedIps, JSON_PRETTY_PRINT));\n        }\n\n        $this->logger->info(\"IP unblocked: $ip\");\n        return true;\n    }",
        "originalFile": "<?php\n\nnamespace App\\Services;\n\nuse SystemAdmin\\Helpers\\ConfigLoader;\nuse App\\Services\\Traits\\BotDetectionTrait;\nuse App\\Services\\Logger;\nuse App\\Services\\RateLimitingService;\n\n\/**\n * Bot Detection Service mit fail2ban\/nftables-Integration\n * Blockiert unerwünschte Bots basierend auf JSON-Konfiguration\n *\/\nclass BotDetectionService\n{\n    use BotDetectionTrait;\n    private array $config;\n    private Logger $logger;\n    private string $blockedIpsFile;\n    private array $requestCounts = [];\n    private RateLimitingService $rateLimiter;\n    \n    public function __construct()\n    {\n        $configLoader = ConfigLoader::getInstance();\n        $configPath = $configLoader->get('paths.root') . '\/src\/Config\/bot-management.json';\n        \n        if (!file_exists($configPath)) {\n            throw new \\Exception(\"Bot management config not found: $configPath\");\n        }\n        \n        $this->config = json_decode(file_get_contents($configPath), true);\n        if (json_last_error() !== JSON_ERROR_NONE) {\n            throw new \\Exception(\"Invalid bot management config JSON: \" . json_last_error_msg());\n        }\n        \n        $this->logger = new Logger();\n        $this->blockedIpsFile = $configLoader->get('paths.root') . '\/cache\/blocked_ips.json';\n        \n        \/\/ Initialize advanced rate limiting\n        $this->rateLimiter = new RateLimitingService($this->config['rate_limiting']);\n        \n        \/\/ Lade bestehende blockierte IPs\n        $this->loadBlockedIps();\n    }\n    \n    \/**\n     * Hauptfunktion: Prüft ob Request blockiert werden soll\n     *\/\n    public function shouldBlockRequest(): bool\n    {\n        if (!$this->config['settings']['enabled']) {\n            return $this->returnBotDetectionResult(false, 'service_disabled');\n        }\n        \n        $clientIp = $this->getClientIp();\n        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';\n        \n        \/\/ 1. Whitelist-Prüfung (höchste Priorität)\n        if ($this->isWhitelisted($clientIp, $userAgent)) {\n            $this->logDetectionEvent('whitelist_match', $clientIp, $userAgent);\n            return $this->returnBotDetectionResult(false, 'whitelisted');\n        }\n        \n        \/\/ 2. Blacklist-Prüfung\n        if ($this->isBlacklisted($clientIp, $userAgent)) {\n            $this->blockRequest($clientIp, $userAgent, 'blacklist_match');\n            return $this->returnBotDetectionResult(true, 'blacklisted');\n        }\n        \n        \/\/ 3. Advanced Rate Limiting\n        $isAuthenticated = $this->isUserAuthenticated();\n        $rateLimitResult = $this->rateLimiter->isRateLimited($clientIp, $userAgent, $isAuthenticated);\n        \n        if ($rateLimitResult['limited']) {\n            $this->handleRateLimitViolation($clientIp, $userAgent, $rateLimitResult);\n            return $this->returnBotDetectionResult(true, 'rate_limited');\n        }\n        \n        return $this->returnBotDetectionResult(false, 'allowed');\n    }\n    \n    \/**\n     * Whitelist-Prüfung\n     *\/\n    private function isWhitelisted(string $ip, string $userAgent): bool\n    {\n        $whitelist = $this->config['whitelist'];\n        \n        \/\/ Exakte User-Agent Matches\n        if (in_array($userAgent, $whitelist['user_agents'] ?? [])) {\n            return true;\n        }\n        \n        \/\/ User-Agent Pattern Matches\n        if ($this->checkUserAgentRegexPatterns($userAgent, $whitelist['user_agent_patterns'] ?? [])) {\n            return true;\n        }\n        \n        \/\/ IP-Ranges\n        if ($this->checkIpInRanges($ip, $whitelist['ips'] ?? [])) {\n            return true;\n        }\n        \n        return $this->checkAndReturnResult(false);\n    }\n    \n    \/**\n     * Blacklist-Prüfung\n     *\/\n    private function isBlacklisted(string $ip, string $userAgent): bool\n    {\n        $blacklist = $this->config['blacklist'];\n        \n        \/\/ Exakte User-Agent Matches\n        if (in_array($userAgent, $blacklist['exact_user_agents'] ?? [])) {\n            return true;\n        }\n        \n        \/\/ Einzelne User-Agent Keywords\n        if ($this->checkUserAgentPattern($userAgent, $blacklist['user_agents'] ?? [])) {\n            return true;\n        }\n        \n        \/\/ User-Agent Pattern Matches\n        if ($this->checkUserAgentRegexPatterns($userAgent, $blacklist['user_agent_patterns'] ?? [])) {\n            return true;\n        }\n        \n        \/\/ IP-Ranges\n        if ($this->checkIpInRanges($ip, $blacklist['ips'] ?? [])) {\n            return true;\n        }\n        \n        return $this->checkAndReturnResult(false);\n    }\n    \n    \/**\n     * Prüft ob User authentifiziert ist\n     *\/\n    private function isUserAuthenticated(): bool\n    {\n        if (session_status() === PHP_SESSION_NONE) {\n            session_start();\n        }\n        \n        \/\/ Check verschiedene Session-Indikatoren\n        return isset($_SESSION['admin_authenticated']) ||\n               isset($_SESSION['user_authenticated']) ||\n               isset($_SESSION['crm_contact_id']) ||\n               !empty($_COOKIE['crm_session']);\n    }\n    \n    \/**\n     * Behandelt Rate Limit Verletzungen basierend auf Level\n     *\/\n    private function handleRateLimitViolation(string $ip, string $userAgent, array $rateLimitResult): void\n    {\n        $level = $rateLimitResult['level'];\n        $action = $rateLimitResult['action'];\n        $remainingSeconds = $rateLimitResult['remaining_seconds'] ?? 0;\n        \n        \/\/ Logging\n        $this->logger->warning(\"Rate limit violation: $level | IP: $ip | Action: $action | Remaining: {$remainingSeconds}s\");\n        \n        switch ($action) {\n            case 'log_warning':\n                \/\/ Nur loggen, kein Blocking\n                break;\n                \n            case 'temporary_delay':\n                \/\/ 2-Sekunden Delay\n                sleep(2);\n                break;\n                \n            case 'temporary_block':\n                \/\/ Temporärer Block mit HTTP Response\n                $this->sendRateLimitResponse($remainingSeconds, $level);\n                break;\n                \n            case 'block':\n                $this->sendRateLimitResponse($remainingSeconds, $level);\n                break;\n        }\n    }\n    \n    \/**\n     * Sendet Rate Limit Response\n     *\/\n    private function sendRateLimitResponse(int $remainingSeconds, string $level): void\n    {\n        http_response_code(429); \/\/ Too Many Requests\n        header('Retry-After: ' . $remainingSeconds);\n        header('Content-Type: text\/plain');\n        \n        $message = \"Rate limit exceeded ($level). \";\n        if ($remainingSeconds > 0) {\n            $message .= \"Try again in $remainingSeconds seconds.\";\n        } else {\n            $message .= \"Please slow down your requests.\";\n        }\n        \n        echo $message;\n        exit;\n    }\n    \n    \/**\n     * Request blockieren\n     *\/\n    private function blockRequest(string $ip, string $userAgent, string $reason): void\n    {\n        \/\/ Logging\n        if ($this->config['logging']['blocked_attempts']) {\n            $this->logger->warning(\"Bot blocked: $reason | IP: $ip | UA: \" . substr($userAgent, 0, 100));\n        }\n\n        \/\/ IP zu blockierten IPs hinzufügen\n        $this->addToBlockedIps($ip, $reason);\n        \n        \/\/ HTTP Response senden\n        if ($this->config['actions']['return_403']) {\n            http_response_code(403);\n            header('Content-Type: text\/plain');\n            echo \"Access denied. Automated traffic not permitted.\";\n            exit;\n        } elseif ($this->config['actions']['return_404']) {\n            http_response_code(404);\n            header('Content-Type: text\/plain');\n            echo \"Not Found\";\n            exit;\n        }\n    }\n    \n    \/**\n     * Hilfsfunktionen\n     *\/\n    private function getClientIp(): string\n    {\n        $headers = [\n            'HTTP_CF_CONNECTING_IP',     \/\/ Cloudflare\n            'HTTP_X_FORWARDED_FOR',      \/\/ Proxy\n            'HTTP_X_FORWARDED',          \n            'HTTP_X_CLUSTER_CLIENT_IP',  \n            'HTTP_FORWARDED_FOR',        \n            'HTTP_FORWARDED',            \n            'REMOTE_ADDR'                \/\/ Standard\n        ];\n        \n        foreach ($headers as $header) {\n            if (!empty($_SERVER[$header])) {\n                $ips = explode(',', $_SERVER[$header]);\n                $ip = trim($ips[0]);\n                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {\n                    return $ip;\n                }\n            }\n        }\n        \n        return $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';\n    }\n    \n    private function ipInRange(string $ip, string $range): bool\n    {\n        if (strpos($range, '\/') === false) {\n            return $ip === $range;\n        }\n        \n        list($subnet, $mask) = explode('\/', $range);\n        $ip_long = ip2long($ip);\n        $subnet_long = ip2long($subnet);\n        $mask_long = ~((1 << (32 - $mask)) - 1);\n        \n        return ($ip_long & $mask_long) === ($subnet_long & $mask_long);\n    }\n    \n    private function looksLikeBot(string $userAgent): bool\n    {\n        $botKeywords = ['bot', 'crawler', 'spider', 'scraper', 'curl', 'wget'];\n        return $this->checkUserAgentPattern(strtolower($userAgent), $botKeywords);\n    }\n    \n    private function loadBlockedIps(): void\n    {\n        if (file_exists($this->blockedIpsFile)) {\n            $data = json_decode(file_get_contents($this->blockedIpsFile), true);\n            \/\/ Cleanup expired blocks here if needed\n        }\n    }\n    \n    private function addToBlockedIps(string $ip, string $reason): void\n    {\n        $blockedIps = [];\n        if (file_exists($this->blockedIpsFile)) {\n            $blockedIps = json_decode(file_get_contents($this->blockedIpsFile), true) ?? [];\n        }\n        \n        $blockedIps[$ip] = [\n            'reason' => $reason,\n            'blocked_at' => time(),\n            'expires_at' => time() + ($this->config['settings']['block_duration_minutes'] * 60)\n        ];\n        \n        file_put_contents($this->block... [TRUNCATED-c936c16a506a6a81]",
        "structuredPatch": [
            {
                "oldStart": 333,
                "oldLines": 23,
                "newStart": 333,
                "newLines": 14,
                "lines": [
                    "     ",
                    "     public function unblockIp(string $ip): bool",
                    "     {",
                    "-        \/\/ Remove from JSON file",
                    "         if (file_exists($this->blockedIpsFile)) {",
                    "             $blockedIps = json_decode(file_get_contents($this->blockedIpsFile), true) ?? [];",
                    "             unset($blockedIps[$ip]);",
                    "             file_put_contents($this->blockedIpsFile, json_encode($blockedIps, JSON_PRETTY_PRINT));",
                    "         }",
                    "-        ",
                    "-        \/\/ Remove UFW rule",
                    "-        try {",
                    "-            $ufwCmd = \"sudo ufw delete deny from $ip\";",
                    "-            shell_exec($ufwCmd . ' 2>&1');",
                    "-            $this->logger->info(\"UFW rule removed for IP: $ip\");",
                    "-            return true;",
                    "-        } catch (\\Exception $e) {",
                    "-            $this->logger->error(\"Failed to remove UFW rule for $ip: \" . $e->getMessage());",
                    "-            return false;",
                    "-        }",
                    "+",
                    "+        $this->logger->info(\"IP unblocked: $ip\");",
                    "+        return true;",
                    "     }",
                    "     ",
                    "     public function getConfig(): array"
                ]
            }
        ],
        "userModified": false,
        "replaceAll": false
    }
}
← Vorheriger Zur Liste Nächster →