"OK", "clean" => false, "filter" => "length_chars", "hit" => "", "message" => "Message too short."]); } else if (str_word_count($msg_lower) < MSG_MIN_WORDS) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "length_words", "hit" => "", "message" => "Message too short."]); } } // // Check email domain // $banneddomainlist = file(BANNED_EMAIL_DOMAINS, FILE_IGNORE_NEW_LINES); foreach ($banneddomainlist as $domain) { if ($email_domain == $domain) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "domain", "hit" => $domain, "message" => "Emails from \"" . htmlspecialchars($domain) . "\" are not allowed because of spam/abuse." . ($domain == "googlemail.com" ? " (Hint: use gmail.com instead)" : "")]); } } // // Check if email address is sketchy // if (!empty($email_parts) && count($email_parts) == 2) { if ($email_parts[0] == $email_parts[1]) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "email_fake", "hit" => "", "message" => "Unacceptable email address."]); } } if (!empty($contactformdomain)) { if ($contactformdomain == $email_domain && $email_parts[0] != "test") { exitWithJson(["status" => "OK", "clean" => false, "filter" => "email_self", "hit" => "", "message" => "Please use your own email address, not ours."]); } } // // Check for blocked spammy words // $bannedwordlist = file(BANNED_WORDLIST, FILE_IGNORE_NEW_LINES); foreach ($bannedwordlist as $word) { if (strpos($msg_lower, $word) !== false) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "word", "hit" => $word, "message" => "\"" . htmlspecialchars($word) . "\" is not allowed because of spam/abuse."]); } } // // Lookup reported client IP address against stopforumspam.com CIDR range list // /** * https://stackoverflow.com/a/594134 */ function cidr_match($ip, $range) { list ($subnet, $bits) = explode('/', $range); if ($bits === null) { $bits = 32; } $ip = ip2long($ip); $subnet = ip2long($subnet); $mask = -1 << (32 - $bits); $subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned return ($ip & $mask) == $subnet; } if (filter_var($clientip, FILTER_VALIDATE_IP, [FILTER_FLAG_IPV4])) { $bannedipcidrlist = file(BANNED_IP_CIDR, FILE_IGNORE_NEW_LINES); foreach ($bannedipcidrlist as $cidr) { if (cidr_match($clientip, $cidr)) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "stopforumspam_toxic_ip_cidr", "hit" => $clientip, "message" => "Your computer's IP address is on a spam blacklist."]); } } } // // Lookup reported client IP address against stopforumspam.com full IP list // if (filter_var($clientip, FILTER_VALIDATE_IP)) { $bannediplist = file(BANNED_IP_LIST, FILE_IGNORE_NEW_LINES); foreach ($bannediplist as $ip) { if ($clientip == $ip) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "stopforumspam_banned_ip", "hit" => $clientip, "message" => "Your computer's IP address is blacklisted for sending spam."]); } } } // // Lookup reported client IP address to see if it's in a botnet or something and sending spam // try { if (filter_var($clientip, FILTER_VALIDATE_IP, [FILTER_FLAG_IPV4])) { $blacklist = "xbl.spamhaus.org"; $url = implode(".", array_reverse(explode(".", $clientip))) . "." . $blacklist; // Cache IPs so we don't do a DNS lookup each time $cacheresp = $memcache->get("net.contactspam.$url"); if ($cacheresp !== false) { $dns_result = $cacheresp; } else { $dns_result = `host -t A $url b.gns.spamhaus.org`; $memcache->set("net.contactspam.$url", $dns_result, 60 * 60 * 24); } if (strpos($dns_result, "NXDOMAIN") === false && strpos($dns_result, "127.0.") !== false) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "spamhaus_xbl", "hit" => $clientip, "message" => "Your computer or a device on your network is infected with a virus and is sending spam messages, so our system is blocking your message."]); } } } catch (Exception $ex) { } // // Check domains in message against blacklists // $lists = [ "multi.surbl.org", "dbl.spamhaus.org", "black.uribl.com" ]; $bannedspamdomains = file(BANNED_SPAM_DOMAINS, FILE_IGNORE_NEW_LINES); try { // Matches domain names $regex = "/([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+)/i"; preg_match_all($regex, urldecode($message), $matches); // Remove any domains on the whitelist before doing lookup $domainlist = []; $whitelistdomainlist = file(WHITELIST_DOMAINS, FILE_IGNORE_NEW_LINES); foreach ($matches[0] as $match) { $match = strtolower($match); $found = false; foreach ($whitelistdomainlist as $domain) { if ($domain == $match) { $found = true; } } if (!$found) { $domainlist[] = $match; if (strpos($match, "www.") === 0) { // starts with www, let's strip it and add both to the list to check $domainlist[] = substr($match, 4); } } } foreach ($domainlist as $d) { // check local domain blacklist foreach ($bannedspamdomains as $word) { if ($word == $d) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "stopforumspam_domains", "hit" => $word, "message" => "Your message contains a domain ($d) that has been linked to recent spam. Message not sent."]); } } } // do online searches only after we've checked the local lists foreach ($domainlist as $d) { // check online blacklists foreach ($lists as $blacklist) { $url = "$d.$blacklist"; // Cache result so we don't do a DNS lookup each time $cacheresp = $memcache->get("net.contactspam.$url"); if ($cacheresp !== false) { $dns_result = $cacheresp; } else { $dns_results = dns_get_record($url); $dns_result = count($dns_results) > 0; $memcache->set("net.contactspam.$url", "$dns_result", 60 * 60 * 24); } if ($dns_result) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "$blacklist", "hit" => $d, "message" => "Your message contains a domain ($d) that has been linked to recent spam or criminal activity. Message not sent."]); } } } } catch (Exception $ex) { } // Check local spammer database if (env("require_database")) { try { if (!empty($clientip)) { if ($database->has("net_contactspam_spammers", ["ip" => $clientip])) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "netsyms_ip_blacklist", "hit" => $clientip, "message" => "A computer at your IP address has sent spam in the past. Your message has been blocked."]); } } if (!empty($email_lower)) { if ($database->has("net_contactspam_spammers", ["email" => $email_lower])) { exitWithJson(["status" => "OK", "clean" => false, "filter" => "netsyms_email_blacklist", "hit" => $email_lower, "message" => "Someone put your email as the from address on a spam message. Your message has been blocked."]); } } } catch (Exception $ex) { // skip } } // // Well if we got here then the message tested negative for spam // exitWithJson(["status" => "OK", "clean" => true, "filter" => null, "hit" => null]);