diff --git a/contact-handler.php b/contact-handler.php index 977eb4e..84677f9 100644 --- a/contact-handler.php +++ b/contact-handler.php @@ -112,6 +112,32 @@ 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.'); @@ -149,16 +175,42 @@ if (isset($_POST['website']) && !empty($_POST['website'])) { sendResponse(false, 'Spam detected'); } -// Check for spam keywords -$spamKeywords = ['viagra', 'casino', 'lottery', 'bitcoin', 'forex', 'loan', 'debt', 'pharmacy']; -$messageContent = strtolower($message . ' ' . $name . ' ' . $company); +// 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); diff --git a/quote-handler.php b/quote-handler.php index 5a26686..eb433c5 100644 --- a/quote-handler.php +++ b/quote-handler.php @@ -8,6 +8,18 @@ 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 function checkRateLimit() { $ip = $_SERVER['REMOTE_ADDR']; @@ -71,11 +83,47 @@ if ($_SERVER['REQUEST_METHOD'] !== 'POST') { sendResponse(false, 'Invalid request method'); } +// Validate CSRF token +if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) { + sendResponse(false, 'Security validation failed. Please refresh the page and try again.'); +} + +// 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.'); } +// Spam protection - honeypot field +if (isset($_POST['website']) && !empty($_POST['website'])) { + sendResponse(false, 'Spam detected'); +} + // Validate and sanitize inputs $services = $_POST['services'] ?? []; $project_scale = validateInput($_POST['project_scale'] ?? '', 'text'); @@ -119,6 +167,42 @@ if (!empty($errors)) { sendResponse(false, implode('. ', $errors)); } +// Enhanced spam protection - content filtering +$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' +]; + +$contentToCheck = strtolower($requirements . ' ' . $name . ' ' . $company . ' ' . $data_sources); +foreach ($spamKeywords as $keyword) { + if (strpos($contentToCheck, $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 < 10) { // Less than 10 seconds for quote form (more complex) + sendResponse(false, 'Form submitted too quickly'); +} + // Sanitize services array $services = array_map(function($service) { return htmlspecialchars(trim($service), ENT_QUOTES, 'UTF-8'); diff --git a/quote.php b/quote.php index 7545723..8829c12 100644 --- a/quote.php +++ b/quote.php @@ -1,741 +1,750 @@ - - - - - - - <?php echo htmlspecialchars($page_title); ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Skip to main content - - - - - -
-
-
-

Free Web Scraping & Data Analytics Quote - UK Data Services

-

Tell us about your project and we'll provide a detailed proposal within 24 hours

-
-
- - -
-
-
-
- -
-
- 1 - What type of data services do you need? -
-
- - - - - - -
-
- - -
-
- 2 - What's the scale of your project? -
-
- - - - -
-
- - -
-
- 3 - When do you need this completed? -
-
- - - - -
-
- - -
-
- 4 - Your contact information -
-
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
- - -
-
- 5 - Project details -
-
- - -
-
- - -
-
- - -
-
- - - -
-
-
-
-
- - - - - - - - + + + + + + + <?php echo htmlspecialchars($page_title); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + + + +
+
+
+

Free Web Scraping & Data Analytics Quote - UK Data Services

+

Tell us about your project and we'll provide a detailed proposal within 24 hours

+
+
+ + +
+
+
+
+ + + + + +
+
+ 1 + What type of data services do you need? +
+
+ + + + + + +
+
+ + +
+
+ 2 + What's the scale of your project? +
+
+ + + + +
+
+ + +
+
+ 3 + When do you need this completed? +
+
+ + + + +
+
+ + +
+
+ 4 + Your contact information +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ 5 + Project details +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +
+
+
+
+
+ + + + + + + + \ No newline at end of file