/home/suroeste/public_html/payments.transportessuroeste.com/src/Middleware
NameSizeModeActions
AuthMiddleware.php55210644editdlrm
RateLimiter.php67230644editdlrm
SecurityMiddleware.php97050644editdlrm
Edit: /home/suroeste/public_html/payments.transportessuroeste.com/src/Middleware/SecurityMiddleware.php (9705B)
setSecurityHeaders(); $this->validateRequest(); $this->detectSuspiciousPatterns(); } /** * Establecer headers de seguridad */ private function setSecurityHeaders(): void { // Prevenir clickjacking header('X-Frame-Options: DENY'); // Prevenir MIME sniffing header('X-Content-Type-Options: nosniff'); // XSS Protection header('X-XSS-Protection: 1; mode=block'); // Referrer Policy header('Referrer-Policy: strict-origin-when-cross-origin'); // Content Security Policy header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://checkout.epayco.co; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.epayco.co https://checkout.epayco.co;"); // Strict Transport Security (solo en producción con HTTPS) if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') { header('Strict-Transport-Security: max-age=31536000; includeSubDomains'); } // Cache control para APIs header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Pragma: no-cache'); // Tipo de contenido header('Content-Type: application/json; charset=utf-8'); } /** * Validar la petición */ private function validateRequest(): void { // Validar método HTTP $allowedMethods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']; if (!in_array($_SERVER['REQUEST_METHOD'], $allowedMethods)) { throw new SecurityException('Método HTTP no permitido', 405); } // Validar Content-Type para POST/PUT if (in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PUT'])) { $contentType = $_SERVER['CONTENT_TYPE'] ?? ''; // Permitir form-data para callbacks de ePayco $isFormData = strpos($contentType, 'application/x-www-form-urlencoded') !== false || strpos($contentType, 'multipart/form-data') !== false; $isJson = strpos($contentType, 'application/json') !== false; // Solo validar si hay body $body = self::getRequestBody(); if (!empty($body) && !$isJson && !$isFormData) { // Permitir si es callback de ePayco (sin Content-Type correcto a veces) $uri = $_SERVER['REQUEST_URI'] ?? ''; if (strpos($uri, 'callback') === false && strpos($uri, 'webhook') === false) { throw new SecurityException('Content-Type debe ser application/json', 415); } } } // Validar tamaño del body $contentLength = $_SERVER['CONTENT_LENGTH'] ?? 0; $maxSize = 1024 * 1024; // 1MB if ($contentLength > $maxSize) { throw new SecurityException('Payload demasiado grande', 413); } } /** * Detectar patrones sospechosos */ private function detectSuspiciousPatterns(): void { $uri = $_SERVER['REQUEST_URI'] ?? ''; $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $body = self::getRequestBody(); // Patrones de SQL Injection $sqlPatterns = [ '/(\bunion\b.*\bselect\b)/i', '/(\bselect\b.*\bfrom\b)/i', '/(\binsert\b.*\binto\b)/i', '/(\bdelete\b.*\bfrom\b)/i', '/(\bdrop\b.*\btable\b)/i', '/(\bexec\b|\bexecute\b)/i', '/(\'|\").*(--)/', '/(\bor\b|\band\b).*(\b1\b\s*=\s*\b1\b)/i' ]; foreach ($sqlPatterns as $pattern) { if (preg_match($pattern, $uri) || preg_match($pattern, $body)) { LogService::security('sql_injection_attempt', 'Posible SQL Injection detectado', [ 'uri' => $uri, 'ip' => LogService::getClientIp() ]); throw new SecurityException('Solicitud bloqueada por seguridad', 403); } } // Patrones de XSS $xssPatterns = [ '/]*>/i', '/javascript:/i', '/on\w+\s*=/i', '/