'Invalid or missing service']); exit; } // --- Secrets (move to environment variables in production) --- function envOrDefault(string $key, string $default = ''): string { $value = getenv($key); return ($value !== false && $value !== '') ? $value : $default; } $apiNinjasKey = envOrDefault('SENTINEL_API_NINJAS_KEY', 'qOAsqB3zCY08kez2FC5nebZFiD3QDcVOmeShndAB'); // --- HTTP helper --- function httpGet(string $url, array $headers = []): array { if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_TIMEOUT => 20, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_HTTPHEADER => $headers, CURLOPT_USERAGENT => 'SentinelAI-Proxy/2.0', ]); $body = curl_exec($ch); $err = curl_error($ch); $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($body === false || $err !== '') { return ['error' => "cURL error: {$err}", 'httpCode' => $code]; } return ['body' => $body, 'httpCode' => $code]; } // Fallback for hosts without cURL $opts = [ 'http' => [ 'method' => 'GET', 'header' => implode("\r\n", array_merge(['User-Agent: SentinelAI-Proxy/2.0'], $headers)), 'timeout' => 20, ], 'ssl' => ['verify_peer' => true], ]; $context = stream_context_create($opts); $body = @file_get_contents($url, false, $context); if ($body === false) { $status = $http_response_header[0] ?? 'HTTP/1.0 0 Error'; return ['error' => 'HTTP request failed: ' . $status, 'httpCode' => 0]; } return ['body' => $body, 'httpCode' => 200]; } function outputJsonError(int $code, string $message): void { http_response_code($code); echo json_encode(['error' => $message]); exit; } // --- Input helpers --- $keyword = $_REQUEST['keyword'] ?? ($input['keyword'] ?? ''); $limit = (int) ($_REQUEST['limit'] ?? ($input['limit'] ?? 20)); $limit = max(1, min(50, $limit)); $ip = $_REQUEST['ip'] ?? ($input['ip'] ?? ''); $ip = filter_var($ip, FILTER_VALIDATE_IP) ? $ip : ''; $domain = $_REQUEST['domain'] ?? ($input['domain'] ?? ''); $domain = preg_replace('/[^a-zA-Z0-9.\-]/', '', $domain); $cveId = $_REQUEST['cveId'] ?? ($input['cveId'] ?? ''); $cveId = preg_replace('/[^A-Za-z0-9\-]/', '', $cveId); $address = $_REQUEST['address'] ?? ($input['address'] ?? '8.8.8.8'); $address = filter_var($address, FILTER_VALIDATE_IP) ? $address : '8.8.8.8'; $url = $_REQUEST['url'] ?? ($input['url'] ?? ''); $length = max(4, min(50, (int) ($_REQUEST['length'] ?? ($input['length'] ?? 16)))); // --- Dispatch --- $result = null; switch ($service) { case 'lookupIP': $targetUrl = $ip !== '' ? "https://ipinfo.io/{$ip}/json" : 'https://ipinfo.io/json'; $result = httpGet($targetUrl); break; case 'searchCVEs': if ($keyword === '') { outputJsonError(400, 'Missing keyword'); } $targetUrl = 'https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=' . rawurlencode($keyword) . '&resultsPerPage=' . $limit; $result = httpGet($targetUrl); break; case 'getCVE': if ($cveId === '') { outputJsonError(400, 'Missing cveId'); } $targetUrl = 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=' . rawurlencode($cveId); $result = httpGet($targetUrl); break; case 'resolveDomain': if ($domain === '') { outputJsonError(400, 'Missing domain'); } $targetUrl = 'https://dns.google/resolve?name=' . rawurlencode($domain) . '&type=A'; $result = httpGet($targetUrl); break; case 'lookupIPNinjas': $targetUrl = 'https://api.api-ninjas.com/v1/iplookup?address=' . rawurlencode($address); $result = httpGet($targetUrl, ['X-Api-Key: ' . $apiNinjasKey]); break; case 'whoisLookup': if ($domain === '') { outputJsonError(400, 'Missing domain'); } $targetUrl = 'https://api.api-ninjas.com/v1/whois?domain=' . rawurlencode($domain); $result = httpGet($targetUrl, ['X-Api-Key: ' . $apiNinjasKey]); break; case 'dnsLookupNinjas': if ($domain === '') { outputJsonError(400, 'Missing domain'); } $targetUrl = 'https://api.api-ninjas.com/v1/dnslookup?domain=' . rawurlencode($domain); $result = httpGet($targetUrl, ['X-Api-Key: ' . $apiNinjasKey]); break; case 'shortenURL': if ($url === '') { outputJsonError(400, 'Missing url'); } $targetUrl = 'https://api.api-ninjas.com/v1/shortenurl?url=' . rawurlencode($url); $result = httpGet($targetUrl, ['X-Api-Key: ' . $apiNinjasKey]); break; case 'generatePassword': $targetUrl = 'https://api.api-ninjas.com/v1/passwordgenerator?length=' . $length; $result = httpGet($targetUrl, ['X-Api-Key: ' . $apiNinjasKey]); break; } if ($result === null) { outputJsonError(500, 'Proxy dispatch failed'); } if (isset($result['error'])) { outputJsonError(502, $result['error']); } // Forward JSON if possible, otherwise raw body $decoded = json_decode($result['body'], true); if (json_last_error() === JSON_ERROR_NONE) { echo json_encode($decoded); } else { echo $result['body']; }