0, 'time' => time()]; } $data = $_SESSION[$key]; // Reset counter if more than 1 hour has passed if (time() - $data['time'] > 3600) { $_SESSION[$key] = ['count' => 0, 'time' => time()]; $data = $_SESSION[$key]; } // Allow max 5 submissions per hour if ($data['count'] >= 5) { return false; } return true; } // Input validation and sanitization function validateInput($data, $type = 'text') { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); // Prevent header injection $data = str_replace(array("\r", "\n", "%0a", "%0d"), '', $data); switch ($type) { case 'email': $email = filter_var($data, FILTER_VALIDATE_EMAIL); // Additional email validation to prevent header injection if ($email && !preg_match('/[\r\n]/', $email)) { return $email; } return false; case 'phone': return preg_match('/^[\+]?[0-9\s\-\(\)]+$/', $data) ? $data : false; case 'text': return strlen($data) > 0 ? $data : false; case 'message': return strlen($data) >= 10 ? $data : false; default: return $data; } } // Response function function sendResponse($success, $message, $data = null) { $response = [ 'success' => $success, 'message' => $message ]; if ($data !== null) { $response['data'] = $data; } echo json_encode($response); exit; } // Handle POST requests only if ($_SERVER['REQUEST_METHOD'] !== 'POST') { sendResponse(false, 'Invalid request method'); } // Check referer to prevent external form submissions $allowed_referers = ['ukdataservices.co.uk', 'www.ukdataservices.co.uk', 'localhost']; $referer_valid = false; if (isset($_SERVER['HTTP_REFERER'])) { $referer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); foreach ($allowed_referers as $allowed) { if ($referer_host === $allowed || strpos($referer_host, $allowed) !== false) { $referer_valid = true; break; } } } // Allow direct access for testing but log it if (!$referer_valid && !isset($_SERVER['HTTP_REFERER'])) { error_log("Contact form accessed without referer from IP: " . $_SERVER['REMOTE_ADDR']); } // Check for blocked IPs function checkBlockedIP() { $ip = $_SERVER['REMOTE_ADDR']; $blockFile = 'logs/blocked-ips.txt'; if (file_exists($blockFile)) { $blockedIPs = file($blockFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($blockedIPs as $blockedEntry) { $parts = explode('|', $blockedEntry); if (isset($parts[0]) && $parts[0] === $ip) { $blockTime = isset($parts[1]) ? (int)$parts[1] : 0; // Block for 24 hours if (time() - $blockTime < 86400) { return false; } } } } return true; } // Check for blocked IPs first if (!checkBlockedIP()) { sendResponse(false, 'Access temporarily restricted'); } // Check rate limiting if (!checkRateLimit()) { sendResponse(false, 'Too many requests. Please try again later.'); } // Validate and sanitize inputs $name = validateInput($_POST['name'] ?? '', 'text'); $email = validateInput($_POST['email'] ?? '', 'email'); $company = validateInput($_POST['company'] ?? '', 'text'); $service = validateInput($_POST['service'] ?? '', 'text'); $message = validateInput($_POST['message'] ?? '', 'message'); // Validation $errors = []; if (!$name || strlen($name) < 2) { $errors[] = 'Please enter a valid name (minimum 2 characters)'; } if (!$email) { $errors[] = 'Please enter a valid email address'; } if (!$message) { $errors[] = 'Please provide project details (minimum 10 characters)'; } if (!empty($errors)) { sendResponse(false, implode('. ', $errors)); } // Spam protection - simple honeypot and content filtering if (isset($_POST['website']) && !empty($_POST['website'])) { // Honeypot field filled - likely spam sendResponse(false, 'Spam detected'); } // Enhanced spam protection - expanded keyword list $spamKeywords = [ 'viagra', 'cialis', 'casino', 'lottery', 'bitcoin', 'forex', 'loan', 'debt', 'pharmacy', 'click here', 'act now', 'limited time', 'risk free', 'guarantee', 'no obligation', 'free money', 'make money fast', 'work from home', 'get rich', 'investment opportunity', 'credit repair', 'refinance', 'consolidate debt', 'weight loss', 'miracle cure', 'lose weight', 'adult content', 'porn', 'sex', 'dating', 'singles', 'webcam', 'escort', 'massage' ]; $messageContent = strtolower($message . ' ' . $name . ' ' . $company); foreach ($spamKeywords as $keyword) { if (strpos($messageContent, $keyword) !== false) { sendResponse(false, 'Invalid content detected'); } } // Bot detection - check for suspicious patterns $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $suspiciousAgents = ['curl', 'wget', 'python', 'bot', 'crawler', 'spider', 'scraper']; foreach ($suspiciousAgents as $agent) { if (stripos($userAgent, $agent) !== false) { sendResponse(false, 'Automated submissions not allowed'); } } // Check submission speed (too fast = likely bot) if (!isset($_SESSION['form_start_time'])) { $_SESSION['form_start_time'] = time(); } $submissionTime = time() - $_SESSION['form_start_time']; if ($submissionTime < 5) { // Less than 5 seconds to fill form sendResponse(false, 'Form submitted too quickly'); } // Update rate limit counter $ip = $_SERVER['REMOTE_ADDR']; $key = 'contact_' . md5($ip); $_SESSION[$key]['count']++; // Prepare email content $to = 'info@ukdataservices.co.uk'; $subject = 'New Contact Form Submission - UK Data Services'; // Create HTML email $emailHTML = ' New Contact Form Submission

New Contact Form Submission

UK Data Services

Name:
' . htmlspecialchars($name) . '
Email:
' . htmlspecialchars($email) . '
Company:
' . htmlspecialchars($company ?: 'Not provided') . '
Service Required:
' . htmlspecialchars($service ?: 'Not specified') . '
Project Details:
' . nl2br(htmlspecialchars($message)) . '
Submission Details:
IP Address: ' . htmlspecialchars($_SERVER['REMOTE_ADDR']) . '
User Agent: ' . htmlspecialchars($_SERVER['HTTP_USER_AGENT']) . '
Timestamp: ' . date('Y-m-d H:i:s') . ' UTC
Referrer: ' . htmlspecialchars($_SERVER['HTTP_REFERER'] ?? 'Direct') . '
'; // Email headers $headers = "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/html; charset=UTF-8\r\n"; $headers .= "From: \"UK Data Services Contact Form\" \r\n"; $headers .= "Reply-To: " . $email . "\r\n"; $headers .= "X-Mailer: PHP/" . phpversion() . "\r\n"; $headers .= "X-Priority: 3\r\n"; // Create logs directory if it doesn't exist if (!file_exists('logs')) { mkdir('logs', 0755, true); } // Send email try { $emailSent = mail($to, $subject, $emailHTML, $headers); if ($emailSent) { // Log successful submission $logEntry = date('Y-m-d H:i:s') . " - Contact form submission from " . $email . " (" . $_SERVER['REMOTE_ADDR'] . ")\n"; file_put_contents('logs/contact-submissions.log', $logEntry, FILE_APPEND | LOCK_EX); sendResponse(true, 'Thank you for your message! We will get back to you within 24 hours.'); } else { // Log failed email $logEntry = date('Y-m-d H:i:s') . " - FAILED contact form submission from " . $email . " (" . $_SERVER['REMOTE_ADDR'] . ")\n"; file_put_contents('logs/contact-errors.log', $logEntry, FILE_APPEND | LOCK_EX); sendResponse(false, 'There was an error sending your message. Please try again or contact us directly.'); } } catch (Exception $e) { // Log exception $logEntry = date('Y-m-d H:i:s') . " - EXCEPTION: " . $e->getMessage() . " from " . $email . " (" . $_SERVER['REMOTE_ADDR'] . ")\n"; file_put_contents('logs/contact-errors.log', $logEntry, FILE_APPEND | LOCK_EX); sendResponse(false, 'There was an error processing your request. Please try again later.'); } ?>