2025-06-07 10:53:32 +01:00
|
|
|
<?php
|
|
|
|
|
// Enhanced Contact Form Handler with Security
|
|
|
|
|
session_start();
|
|
|
|
|
|
|
|
|
|
// Security headers
|
|
|
|
|
header('X-Content-Type-Options: nosniff');
|
|
|
|
|
header('X-Frame-Options: DENY');
|
|
|
|
|
header('X-XSS-Protection: 1; mode=block');
|
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
|
|
|
|
|
|
// CSRF Protection
|
|
|
|
|
function generateCSRFToken() {
|
|
|
|
|
if (!isset($_SESSION['csrf_token'])) {
|
|
|
|
|
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
|
|
|
|
}
|
|
|
|
|
return $_SESSION['csrf_token'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function validateCSRFToken($token) {
|
|
|
|
|
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Rate limiting (simple implementation)
|
|
|
|
|
function checkRateLimit() {
|
|
|
|
|
$ip = $_SERVER['REMOTE_ADDR'];
|
|
|
|
|
$key = 'contact_' . md5($ip);
|
|
|
|
|
|
|
|
|
|
if (!isset($_SESSION[$key])) {
|
|
|
|
|
$_SESSION[$key] = ['count' => 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');
|
|
|
|
|
|
|
|
|
|
switch ($type) {
|
|
|
|
|
case 'email':
|
|
|
|
|
return filter_var($data, FILTER_VALIDATE_EMAIL) ? $data : 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 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');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for spam keywords
|
|
|
|
|
$spamKeywords = ['viagra', 'casino', 'lottery', 'bitcoin', 'forex', 'loan', 'debt', 'pharmacy'];
|
|
|
|
|
$messageContent = strtolower($message . ' ' . $name . ' ' . $company);
|
|
|
|
|
|
|
|
|
|
foreach ($spamKeywords as $keyword) {
|
|
|
|
|
if (strpos($messageContent, $keyword) !== false) {
|
|
|
|
|
sendResponse(false, 'Invalid content detected');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 = '
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<title>New Contact Form Submission</title>
|
|
|
|
|
<style>
|
|
|
|
|
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
|
|
|
|
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
|
|
|
|
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; }
|
|
|
|
|
.content { background: #f9f9f9; padding: 20px; }
|
|
|
|
|
.field { margin-bottom: 15px; padding: 10px; background: white; border-left: 4px solid #667eea; }
|
|
|
|
|
.field-label { font-weight: bold; color: #667eea; }
|
|
|
|
|
.footer { text-align: center; padding: 20px; color: #666; font-size: 12px; }
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div class="container">
|
|
|
|
|
<div class="header">
|
|
|
|
|
<h1>New Contact Form Submission</h1>
|
|
|
|
|
<p>UK Data Services</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="content">
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="field-label">Name:</div>
|
|
|
|
|
<div>' . htmlspecialchars($name) . '</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="field-label">Email:</div>
|
|
|
|
|
<div>' . htmlspecialchars($email) . '</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="field-label">Company:</div>
|
|
|
|
|
<div>' . htmlspecialchars($company ?: 'Not provided') . '</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="field-label">Service Required:</div>
|
|
|
|
|
<div>' . htmlspecialchars($service ?: 'Not specified') . '</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="field-label">Project Details:</div>
|
|
|
|
|
<div>' . nl2br(htmlspecialchars($message)) . '</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="field-label">Submission Details:</div>
|
|
|
|
|
<div>
|
|
|
|
|
<strong>IP Address:</strong> ' . htmlspecialchars($_SERVER['REMOTE_ADDR']) . '<br>
|
|
|
|
|
<strong>User Agent:</strong> ' . htmlspecialchars($_SERVER['HTTP_USER_AGENT']) . '<br>
|
|
|
|
|
<strong>Timestamp:</strong> ' . date('Y-m-d H:i:s') . ' UTC<br>
|
|
|
|
|
<strong>Referrer:</strong> ' . htmlspecialchars($_SERVER['HTTP_REFERER'] ?? 'Direct') . '
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="footer">
|
|
|
|
|
<p>This email was sent from the UK Data Services contact form.</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
|
|
|
|
</html>';
|
|
|
|
|
|
|
|
|
|
// 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\" <noreply@ukdataservices.co.uk>\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);
|
|
|
|
|
|
|
|
|
|
// Send auto-reply to user
|
|
|
|
|
$autoReplySubject = 'Thank you for contacting UK Data Services';
|
|
|
|
|
$autoReplyHTML = '
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<title>Thank you for your inquiry</title>
|
|
|
|
|
<style>
|
|
|
|
|
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
|
|
|
|
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
|
|
|
|
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; }
|
|
|
|
|
.content { background: #f9f9f9; padding: 20px; }
|
|
|
|
|
.cta { background: #667eea; color: white; padding: 15px; text-align: center; margin: 20px 0; }
|
|
|
|
|
.footer { text-align: center; padding: 20px; color: #666; font-size: 12px; }
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div class="container">
|
|
|
|
|
<div class="header">
|
|
|
|
|
<h1>Thank You for Your Inquiry</h1>
|
|
|
|
|
<p>UK Data Services</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="content">
|
|
|
|
|
<p>Dear ' . htmlspecialchars($name) . ',</p>
|
|
|
|
|
|
|
|
|
|
<p>Thank you for contacting UK Data Services. We have received your inquiry and one of our data specialists will review your requirements and respond within 24 hours.</p>
|
|
|
|
|
|
|
|
|
|
<div class="cta">
|
|
|
|
|
<h3>What happens next?</h3>
|
2025-06-07 12:58:04 +01:00
|
|
|
<p>• Our team will analyse your data requirements<br>
|
|
|
|
|
• We will prepare a customised solution proposal<br>
|
2025-06-07 10:53:32 +01:00
|
|
|
• You will receive a detailed quote and timeline<br>
|
|
|
|
|
• We can schedule a consultation call if needed</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<p>In the meantime, feel free to:</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li>Call us directly at <strong>+44 1692 689150</strong></li>
|
|
|
|
|
<li>Visit our website for more information about our services</li>
|
|
|
|
|
<li>Follow us on LinkedIn for industry insights</li>
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
<p>We look forward to helping you transform your business with professional data solutions.</p>
|
|
|
|
|
|
|
|
|
|
<p>Best regards,<br>
|
|
|
|
|
<strong>The UK Data Services Team</strong></p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="footer">
|
|
|
|
|
<p>UK Data Services | Professional Data Solutions<br>
|
|
|
|
|
Website: https://ukdataservices.co.uk | Phone: +44 1692 689150</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
|
|
|
|
</html>';
|
|
|
|
|
|
|
|
|
|
$autoReplyHeaders = "MIME-Version: 1.0\r\n";
|
|
|
|
|
$autoReplyHeaders .= "Content-Type: text/html; charset=UTF-8\r\n";
|
|
|
|
|
$autoReplyHeaders .= "From: \"UK Data Services\" <info@ukdataservices.co.uk>\r\n";
|
|
|
|
|
$autoReplyHeaders .= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
|
|
|
|
|
|
|
|
|
mail($email, $autoReplySubject, $autoReplyHTML, $autoReplyHeaders);
|
|
|
|
|
|
|
|
|
|
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.');
|
|
|
|
|
}
|
|
|
|
|
?>
|