Serverseitiger Spam-Schutz für Elementor Pro Forms

Zweck

Blockiert typische Bot-Anfragen in Elementor-Pro-Formularen direkt während der serverseitigen Formularvalidierung, bevor die Anfrage verarbeitet wird.

  • keine erfolgreiche Formularübermittlung
  • keine Mail wird versendet
  • Spam wird nicht als erfolgreiche Anfrage verarbeitet

Der Schutz arbeitet serverseitig und ist:

  • unabhängig vom Theme
  • unabhängig von JavaScript-Prüfungen im Browser
  • unabhängig von Sessions
  • DSGVO-neutral
  • hosting-unabhängig

Technische Funktionsweise

Der Spam-Guard verwendet direkt die serverseitige Validierung von Elementor Pro:

elementor_pro/forms/validation

Dadurch werden nicht mehr rohe POST-Daten auf init geprüft, sondern die von Elementor bereits erkannten und aufbereiteten Formularfelder.

Der Code prüft:

  1. Welche Felder Elementor für das aktuelle Formular übergibt
  2. Ob das Feld zu den definierten Freitextfeldern gehört
  3. Ob der Inhalt typische Gibberish-/Bot-Muster enthält

Wird Spam erkannt, setzt der Guard über Elementors eigenen Ajax-Handler einen Validierungsfehler:

$ajax_handler->add_error()

Das Formular wird dadurch nicht erfolgreich abgesendet.

Wichtig: nicht über init / $_POST prüfen

Eine ältere Version des Spam-Guards prüfte Elementor-Formulare bereits auf init über:

$_POST['form_fields']

Diese Methode hat sich als unzuverlässig erwiesen: Testweise eingetragener Spam konnte trotz eindeutig passender Gibberish-Regeln das Formular passieren.

Für Elementor-Pro-Formulare daher immer den nativen Hook elementor_pro/forms/validation verwenden.

Abgedeckte Spam-Muster

Blockiert unter anderem:

  • lange zufällige Zeichenketten ohne Leerzeichen
  • lange Wörter ohne Vokale
  • sehr lange einzelne Wörter
  • auffällig zufällige Groß-/Kleinschreibung
  • starke Wortwiederholungen

Der Spam-Guard prüft ausschließlich definierte semantische Freitextfelder wie Name, Betreff, Nachricht, Firma, Hochschule oder Studiengang.

E-Mail-Adressen, Telefonnummern, Checkboxen und andere nicht ausdrücklich definierte Felder werden bewusst nicht geprüft.

Einsatzbereich

Diese Version ist ausschließlich für Elementor Pro Forms vorgesehen.

Andere Formularsysteme brauchen eine eigene Integration in deren jeweilige serverseitige Validierung.

Einbau

Plugin: Code Snippets
Ausführung: Überall

<?php

// ============================================================
// SPAM GUARD – NUR ELEMENTOR FORMS
// ============================================================

add_action('elementor_pro/forms/validation', function ($record, $ajax_handler) {

    // --------------------------------------------------------
    // Elementor-Felder holen
    // --------------------------------------------------------

    $fields = $record->get('fields');

    if (empty($fields) || !is_array($fields)) {
        return;
    }


    // --------------------------------------------------------
    // Felder, die auf Gibberish geprüft werden
    // --------------------------------------------------------

    /*
     * E-Mail und Telefon werden bewusst nicht geprüft.
     */
    $fields_to_check = [
        'name',
        'first_name',
        'last_name',
        'vorname',
        'nachname',

        'subject',
        'betreff',

        'message',
        'nachricht',
        'kommentar',

        'company',
        'firma',

        'hochschule',
        'studiengang',
    ];


    // --------------------------------------------------------
    // Gibberish-Erkennung
    // --------------------------------------------------------

    $is_gibberish = function (string $value): bool {

        $value = trim($value);

        if (strlen($value) < 8) {
            return false;
        }

        $tokens = preg_split('/\s+/', strtolower($value));

        $tokens = array_filter(
            $tokens,
            fn($t) => strlen($t) >= 5
        );

        $unique = array_unique($tokens);


        // Viele Wiederholungen
        if (
            count($tokens) >= 3 &&
            count($unique) < count($tokens) * 0.6
        ) {
            return true;
        }


        // Langer String ohne Leerzeichen
        if (
            strlen($value) >= 30 &&
            strpos($value, ' ') === false
        ) {
            return true;
        }


        // Lange Wörter ohne Vokale
        foreach ($tokens as $token) {

            if (
                strlen($token) >= 9 &&
                !preg_match('/[aeiouäöüy]/i', $token)
            ) {
                return true;
            }
        }


        // Sehr langes einzelnes Wort ohne Leerzeichen
        if (
            strpos($value, ' ') === false &&
            strlen($value) >= 18
        ) {
            return true;
        }


        // Zufällige Groß-/Kleinschreibung
        // in einem einzelnen längeren Wort
        if (
            strpos($value, ' ') === false &&
            strlen($value) >= 12
        ) {

            preg_match_all(
                '/[a-z][A-Z]|[A-Z][a-z]/',
                $value,
                $matches
            );

            if (count($matches[0]) >= 5) {
                return true;
            }
        }


        return false;
    };


    // --------------------------------------------------------
    // Elementor-Felder prüfen
    // --------------------------------------------------------

    foreach ($fields as $field) {

        $field_id = $field['id'] ?? '';
        $value    = $field['value'] ?? '';

        // Nur vorgesehene Textfelder untersuchen
        if (!in_array($field_id, $fields_to_check, true)) {
            continue;
        }

        // Arrays ignorieren, z. B. Checkbox-Gruppen
        if (is_array($value)) {
            continue;
        }

        $value = trim((string) $value);

        if ($value === '') {
            continue;
        }

        // Spam erkannt
        if ($is_gibberish($value)) {

            $ajax_handler->add_error(
                $field_id,
                'Bitte überprüfe deine Eingabe.'
            );

            return;
        }
    }

}, 10, 2);

?>

Test

Nach dem Einbau mit einer normalen Anfrage und anschließend mit einem eindeutigen Gibberish-String testen.

Beispiel:

YRBVOEXL0Cpup1cMEB4YR6kuKss818iaRhSU2nrA93fwvuM99bKllvG

Der Gibberish-Test muss einen Validierungsfehler auslösen. Eine normale Anfrage muss unverändert durchgehen.