Files
ukaiautomation/contact-handler.php
root 624613a0d0 Secure contact form and email configuration
- Add email header injection prevention
- Implement referer checking for form submissions
- Create .htaccess security rules for handlers
- Add secure email configuration file
- Include UTF-8 database backup
- Restrict access to sensitive files

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-08 03:42:09 +00:00

341 lines
12 KiB
PHP

<?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');
// 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 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>
<p>• Our team will analyse your data requirements<br>
• We will prepare a customised solution proposal<br>
• 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.');
}
?>