' . '' . '' . ''; } function app_spam_guard_honeypot_tripped(): bool { return trim((string)($_POST['contact_reference'] ?? '')) !== ''; } /** * Nimmt die Domain der Adresse ueberhaupt Mail an? Ohne MX-Eintrag gilt nach * RFC 5321 der A/AAAA-Record als Ziel, deshalb beide als Rueckfallebene. * * Bewusst fail-open: steht checkdnsrr() nicht zur Verfuegung, wird die * Adresse durchgelassen. Eine kaputte DNS-Aufloesung darf keine echten * Registrierungen blockieren. */ function app_spam_guard_email_domain_resolves(string $email): bool { if (!function_exists('checkdnsrr')) { return true; } $at = strrpos($email, '@'); if ($at === false) { return false; } $domain = rtrim(substr($email, $at + 1), '.'); if ($domain === '' || !str_contains($domain, '.')) { return false; } return @checkdnsrr($domain, 'MX') || @checkdnsrr($domain, 'A') || @checkdnsrr($domain, 'AAAA'); } /** * Ein Treffer wird protokolliert, aber dem Absender gegenueber nicht * benannt: er bekommt dieselbe generische Meldung wie bei einem * ausgereizten Rate-Limit. So verraet die Antwort nicht, welche Huerde * angeschlagen hat, und ein Bot kann sich nicht darauf einstellen. */ function app_spam_guard_log(string $formKey, string $reason): void { error_log(sprintf('Spam-Guard: %s abgewiesen (%s), IP %s', $formKey, $reason, app_client_ip())); }