Comment spam in Wordpress blokkeren scheelt je in elk geval tijd en een hoop rotzooi © Nico van Dijk

Comment spam op je WordPress-site of blog, wie heeft er niet mee te maken gehad? Maar het is vrij simpel om spam in je reacties te blokkeren zonder plugin.

Laatst gewijzigd: 1 oktober 2025

Spammers verzinnen van alles om hun linkjes te kunnen dumpen. Spam via je contactformulier is een bekende truc, maar ook spam in de reacties onder WordPress-posts is geliefd bij spamverspreiders. In veel gevallen gaat het om spamrobots.

Daarom wil je geen spam via je reacties van je WordPress-site

Er zijn allerlei redenen waarom je spam via reacties onder je WordPress-posts wilt vermijden. Je inbox raakt vol met nutteloze berichten, waardoor je meer moeite moet doen om de echt belangrijke mails eruit te filteren. De constante stroom van ongevraagde berichten werkt irritant en kan zelfs stress veroorzaken.

Veel spam bevat phishinglinks, malware of frauduleuze aanbiedingen die je computer of persoonlijke gegevens in gevaar brengen als je er toch per ongeluk op klikt. Tenslotte belasten spammers op grote schaal mailservers, netwerken en spamfilters, waardoor de digitale infrastructuur zwaarder wordt belast.

Spam via je reactieformulier beperken

Ik heb zelf bij wijze van test 4 dagen mijn anti-spamplugin Akismet uitgezet en kreeg in die tijd bijna duizend spamreacties binnen. Verreweg het grootste deel was Russische spam. Maar er zat ook veel spam met linkjes naar pillensites tussen. Het kostte me al met al nog aardig wat tijd ook om al die spam-reacties te lozen. Tip: Zet in het Reactie overzicht van je WordPress-Dashboard rechts bovenaan bij de Scherminstellingen het aantal items per pagina op 100. Vink dan onder het knopje ‘Bulkacties’ het vakje naast Auteur aan en je kunt alle spamreacties in een keer verwijderen.

Spam blokkeren

Blokkeren dus, die spam via je reactieformulier. Gelukkig is spam in je reacties blokkeren niet heel moeilijk. Je kunt daarvoor een gratis plugin als Askimet gebruiken. Die verwijdert op de achtergrond de ergste spam en wat er tussendoor glipt, is niet heel veel en goed herkenbaar. Het nadeel van een plugin is echter dat deze door de makers goed onderhouden moet worden. Tweede nadeel is dat veel plugins, de goede niet te na gesproken, voor onnodig veel code in je website zorgen. Daarnaast vind ik het zelf ook wel een sport om als het even kan functies aan websites toe te voegen door code te schrijven. En dat kunnen AI-bots heel goed voor je doen.

In 3 stappen comment spam blokkeren in WordPress

WordPress zelf biedt beperkte mogelijkheden om spam via je reacties te blokkeren. Bij Instellingen > Discussies kun je natuurlijk alle reacties uit zetten, maar zinvolle reacties van betrokken lezers vind ik zelf van grote waarde. Dus alle reacties blokkeren gaat me een stap te ver. Je kunt echter wel op diezelfde pagina van reactie-instellingen onderaan bij ‘Reacties modereren’ aanvinken dat een reactie in de wachtrij gehouden moet worden als er meer dan 0 links in staan. Spammers sturen namelijk in hun ‘reacties’ vaak veel links mee.

In het vak daaronder kun je ook IP-adressen en afzenders blokkeren, maar dat heeft in de praktijk weinig zin. De spambots wisselen sneller van ip- en mailadres dan een gewoon mens van sokken wisselt.

Comment spam weren van je site

Maar met de hierboven beschreven methode staan de spamreacties nog steeds in je Reactie-overzicht en eigenlijk wil je die bots sowieso niet op je site hebben. Daarvoor moet je twee andere stappen zetten en daarvoor is het nodig dat je via een gratis programma als Filezilla kunt FTP-en.

De eerste stap is onderstaande code aan je htaccess-bestand toe te voegen.

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php$

# Lege User-Agent OF een van onderstaande bots
RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} (spammy-bot|badcrawler|semalt|crawler4j|MJ12bot|AhrefsBot|DotBot|MegaIndex|SEOkicks|LinkpadBot|Mail\.RU_Bot|HTTrack|Wget|libwww-perl|Python-urllib|nikto|massposter) [NC]

RewriteRule ^(.*)$ - [F,L]
</IfModule>

Achter ‘spammy bot’ staat een hele rij met bekende User-Agents. Deze code kijkt of de User-Agent header leeg is (dat is vaak een teken dat het om een bot gaat) of dat er een opgegeven term gebruikt wordt, namelijk spammy-bot of badcrawler. Ze krijgen dan een 403-Forbidden melding terug.

Spam in je reacties bestrijden met een honeypot

De tweede stap bestaat er uit om een spambot in de val te lokken met een zogeheten honeypot in het reactieformulier. Er wordt dan een extra invulveld aan het reactieformulier toegevoegd. Via de ‘<p style=”display:none;’ wordt dit veld voor mensenogen verborgen, dus echte bezoekers zien het niet. Maar spam-bots vullen vaak alle velden in die ze tegenkomen, ook de verborgen velden. Als het veld dus ingevuld is, heb je hoogstwaarschijnlijk te maken met spam via je reactieformulier.

Om deze honeypot aan je site toe te voegen, moet je de onderstaande code aan het functions.php-bestand van je WordPress-theme toevoegen, beter nog om het aan het functions.php-bestand van je Child Theme toe te voegen.

Belangrijk: Maak voordat je je htaccess-bestand en je functions.php-bestand wijzigt, altijd eerst een backup.

function spamfilter_add_honeypot_field() {
    echo '<div style="display:none;" aria-hidden="true"><input type="text" name="cs_hp_website" autocomplete="off" tabindex="-1"></div>';
}
add_action( 'comment_form', 'spamfilter_add_honeypot_field' );

function spamfilter_check_comment( $commentdata ) {
    // Veiligheidscontrole
    if ( ! isset( $commentdata['comment_content'] ) ) {
        return $commentdata;
    }
    
    $content = $commentdata['comment_content'];

    // Honeypot controle
    if ( ! empty( $_POST['cs_hp_website'] ) ) {
        wp_die( esc_html__( 'Spam gedetecteerd: honeypot geactiveerd.', 'suki' ), esc_html__( 'Spam Gedetecteerd', 'THEMENAAM' ), array( 'response' => 403 ) );
    }

In het bovenste gedeelte van de code wordt de honeypot aan je reactieformulier toegevoegd. In het tweede deel van de code wordt gecontroleerd of het honeypot-veld is ingevuld. Zo ja, dan wordt spam gedetecteerd en wordt de reactie geweigerd. Let op: vervang THEMANAAM in de voorlaatte regels door de naam van je eigen (child)theme.

Hoewel deze code in eerste instantie aardig wat rotzooi tegenhield, werd toch niet alle spam geblokkeerd. Het lijkt er dus op dat althans een deel van de spammers de honeypot weet te omzeilen. Of dat echt mensen zijn die handmatig overal spamreacties plaatsen? Eerlijk gezegd kan ik me dat niet voorstellen.

Chinese, Japanse en Russische spam blokkeren

Een analyse van de spam in de wachtrij leerde dat verschillende soorten spamreacties niet geblokkeerd werden:

  • Spam met linkjes
  • Engelstalige spam en
  • Russische spam.

Dat laatste biedt aanknopingspunten. Je kunt namelijk in je htacces-bestand en in je functions-bestand code plaatsen waardoor alle reacties in Chinese, Japanse of Russische tekens automatisch een 403-forbidden reactie krijgen. Ze komen dus niet in je spam wachtrij te staan, dus je hoeft ze ook niet op te ruimen. Plaats onderstaande code in je htaccess-bestand vóór de regels ‘Begin WordPress’.

<IfModule mod_rewrite.c>
RewriteEngine On

# Alleen POST requests (bv. reacties)
RewriteCond %{REQUEST_METHOD} POST

# Blokkeer Cyrillisch (U+0400–U+04FF)
RewriteCond %{QUERY_STRING} [\x{0400}-\x{04FF}] [NC,OR]
RewriteCond %{REQUEST_URI} [\x{0400}-\x{04FF}] [NC,OR]

# Blokkeer Chinees (U+4E00–U+9FFF)
RewriteCond %{QUERY_STRING} [\x{4E00}-\x{9FFF}] [NC,OR]
RewriteCond %{REQUEST_URI} [\x{4E00}-\x{9FFF}] [NC,OR]

# Blokkeer Japans (Hiragana + Katakana)
RewriteCond %{QUERY_STRING} [\x{3040}-\x{30FF}] [NC,OR]
RewriteCond %{REQUEST_URI} [\x{3040}-\x{30FF}] [NC]

# Geef 403 Forbidden
RewriteRule ^ - [F,L]
</IfModule>

Maar hier zit geen blokkade op Engelstalige spam ingebouwd. Daarom kies ik liever voor een andere manier om dit op te lossen, namelijk door een filter aan het functions.php-bestand van je (child)theme toe te voegen. Daar kun je nog een lijst met Engelse-spamwoorden aan je functions.php-bestand toevoegen. De code voor je functions.php-bestand ziet er dan als volgt uit.:

/**
 * ====================================================
 * Veilige spamfilter voor reacties en registratie
 * ====================================================
 */

function spamfilter_add_honeypot_field() {
    echo '<div style="display:none;" aria-hidden="true"><input type="text" name="cs_hp_website" autocomplete="off" tabindex="-1"></div>';
}
add_action( 'comment_form', 'spamfilter_add_honeypot_field' );

function spamfilter_check_comment( $commentdata ) {
    // Veiligheidscontrole
    if ( ! isset( $commentdata['comment_content'] ) ) {
        return $commentdata;
    }
    
    $content = $commentdata['comment_content'];

    // Honeypot controle
    if ( ! empty( $_POST['cs_hp_website'] ) ) {
        wp_die( esc_html__( 'Spam gedetecteerd: honeypot geactiveerd.', 'suki' ), esc_html__( 'Spam Gedetecteerd', 'THEMANAAM' ), array( 'response' => 403 ) );
    }

    // Keyword filter
    $spam_keywords = array(
        'porn', 'sex', 'seks', 'gambling', 'casino', 'cbd', 'crypto', 'forex',
        'viagra', 'cialis', 'poker', 'money', 'loan', 'free access', 'pharmacy', 'pills',
        'bitcoin', 'online store', 'experience', 'darknet', 'vpn'
    );
    
    foreach ( $spam_keywords as $keyword ) {
        if ( stripos( $content, $keyword ) !== false ) {
            wp_die( esc_html__( 'Spam gedetecteerd: verboden trefwoord.', 'suki' ), esc_html__( 'Spam Gedetecteerd', 'THEMANAAM' ), array( 'response' => 403 ) );
        }
    }

Deze code zorgt er voor dat reacties met verboden woorden direct een 403-forbidden-melding terugkrijgen. De spam belandt dus niet eens in je reactie-spam. In het begin zal er best nog wat Engelstalige spam doorheen glippen, maar je kunt de lijst met verboden woorden makkelijker via functions.php uitbreiden dan via je htaccess-bestand. Vervang opnieuw THEMANAAM in de naam van je eigen (child)thema.

Na een eerste test van 24 uur had ik nog maar 3 spamreacties. Eén daarvan was in het Engels en daarom heb ik de lijst met verboden Engelse woorden nog wat uitgebreid. Een andere was in het Russisch, dus die is er kennelijk doorheen geglipt.

Zo pak je mojibake aan

De derde reactie leek ook in Cyrillisch schrift te zijn, maar het bleek ‘mojibake’ te zijn. Toegegeven, ik moest ook even uitzoeken wat dat was. Die tekens ontstaan als WordPress Russische code verkeerd omzet naar Unicode. Dat probleem is weer op te vangen via onderstaande code:

// Controle op niet-ASCII karakters (Russisch, Chinees, Japans, etc.)
    if ( spamfilter_has_non_ascii_chars( $content ) ) {
        wp_die( esc_html__( 'Reactie geblokkeerd: niet-Latijnse tekens zijn niet toegestaan.', 'THEMANAAM' ), esc_html__( 'Spam Gedetecteerd', 'THEMANAAM' ), array( 'response' => 403 ) );
    }

    return $commentdata;
}
add_filter( 'preprocess_comment', 'spamfilter_check_comment' );

/**
 * Uitgebreide detectie van non-ASCII karakters en mojibake
 */
function spamfilter_has_non_ascii_chars( $text ) {
    // Lege string check
    if ( empty( $text ) ) {
        return false;
    }
    
    // Bekende mojibake patronen
    $mojibake_patterns = array(
        "\xC3\xA2\xE2\x82\xAC", // †patroon
        "\xC3\xA2\xE2\x82\xAC\xE2\x84\xA2", // ’ patroon  
        "\xC3\xA2\xE2\x82\xAC\xE2\x80\x9D", // †patroon
        "\xC3\xA2\xE2\x82\xAC\xE2\x80\x9C", // “ patroon
        "\xC3\xA2\xE2\x82\xAC\xE2\x80\xA6", // … patroon
        "\xEF\xBF\xBD", // Replacement character
        "â€", // Veel voorkomend mojibake patroon
        "â€", // Mojibake van smart quotes
        "â™", // Mojibake van trademark symbol
    );
    
    // Controleer op bekende mojibake patronen
    foreach ( $mojibake_patterns as $pattern ) {
        if ( strpos( $text, $pattern ) !== false ) {
            return true;
        }
    }
    
    // Controleer op verdachte byte sequenties (typisch mojibake)
    if ( preg_match( '/\xC3[\x80-\xBF][\xC2-\xF4]/', $text ) ) {
        return true;
    }
    
    // Simpele ASCII controle (origineel)
    return ! ctype_print( $text ) || preg_match( '/[^\x00-\x7F]/', $text );
}

/**
 * Registratie filter
 */
function spamfilter_block_mojibake_registration( $errors, $sanitized_user_login, $user_email ) {
    // Controle op replacement character
    if ( strpos( $sanitized_user_login, "\xEF\xBF\xBD" ) !== false || 
         strpos( $user_email, "\xEF\xBF\xBD" ) !== false ) {
        $errors->add( 'invalid_username', esc_html__( 'Registratie geblokkeerd: ongeldige tekens.', 'THEMANAAM' ) );
        return $errors;
    }
    
    // Controle op non-ASCII in gebruikersnaam
    if ( spamfilter_has_non_ascii_chars( $sanitized_user_login ) ) {
        $errors->add( 'invalid_characters', esc_html__( 'Registratie geblokkeerd: niet-Latijnse tekens in gebruikersnaam.', 'THEMANAAM' ) );
    }

    return $errors;
}
add_filter( 'registration_errors', 'spamfilter_block_mojibake_registration', 10, 3 );

Waarom dit veilige anti-spam blokkade is

Geen belasting op de database

add_filter(‘preprocess_comment’, …): is een WordPress hook die de functie wp_block_foreign_spam_comments activeert voordat een reactie wordt verwerkt en opgeslagen. Dit is cruciaal, want het stelt de code in staat om een reactie te stoppen nog vóórdat deze de database bereikt. Er is dus geen interactie met je WordPress database. De code blokkeert de reactie voordat deze de database bereikt, wat de belasting van je server minimaliseert en de database schoon houdt.

Gerichte filtering op Japans, Russisch en Chinees

Er wordt gericht gefilterd op Japans, Chinees en Russisch door alleen ASCII onder de 127 toe te staan. ASCII-waardes boven 127 worden geblokkeerd. Russische, Chinese en Japanse karakters zijn allemaal boven ASCII 127.

Op veel hosting-servers staan multibyte-functies standaard uit. Deze code bevat geen regex- of multibyte-functies. In eerdere versies van de code stonden wel multibyte-functies en die veroorzaakten bij het indienen van Russische teksten kritieke WordPress-fouten. Ook dan komt er geen spam in je wachtrij, maar dat is niet op de manier waarop je dat wilt 🙂 Je site gaat namelijk onderuit.

Door de regel wp_die() wordt de verwerking van het formulier gestopt. De spammer kan simpelweg niets meer doen en er wordt ook op je site geen actie meer uitgevoerd.

Maatwerkoplossing om Engelstalige spam te weren

Aangezien mijn site ook in het Engels, Frans en Duits te lezen is (via de vlaggetjes bovenaan), kan ik deze code niet toepassen voor het Engels. Bovendien gebruiken Nederlanders vaak Engelse woorden. Daarom is voor Engels een andere aanpak gekozen: De code zoekt naar een lijst van veelvoorkomende Engelse spam-trefwoorden. De lijst is een voorbeeld; je kunt deze aanpassen.

Je kunt dit zelf testen door een Engels-talige reactie met een van de verboden woorden onder een van je artikelen te posten. En om te blokkade op Russische spam te testen, kun je een willekeurig woord door Google Translate in het Russisch laten vertalen en dat in het reactieveld onder een post invoeren.

Het probleem is alleen dat je natuurlijk niet alle woorden uit de Oxford English Dictionary in je functions.php-bestand gaat intikken. Maar op deze website vond ik aanvullende code waarmee je ook hardnekkige spambots tegenhoudt. Ook deze code kun je in je functions.php van je childtheme plaatsen. Wat de code doet is heel simpel: Eerst wordt er een vertraging van 20 seconden ingebouwd voordat je een reactie kunt indien. De meeste spambots wachten niet. Daarna staat er een getal in een verborgen veld dat een bepaalde waard moet bereiken. Als die waarde niet gehaald wordt, heb je waarschijnlijk te maken met een spammer, die vervolgens geblokkeerd wordt.

/*
 * Stop WordPress Spam Comments by WPCookie
 * https://redpishi.com/wordpress-tutorials/stop-wordpress-spam-comments/
 */	
add_action('pre_comment_on_post', function(){
	if (!is_user_logged_in() ) {
$wpcookie = $_POST['wpcookie'];	
if (empty($wpcookie))
wp_die( __("<b>ERROR:</b> Please don't spam! , go back and reload the page and give it another shot.<p><a href='javascript:history.back()'>« Back</a></p>"));
else if ( $wpcookie != "ok" )
wp_die( __("You wrote your comment too fast, go back and reload the page and give it another shot. <p><a href='javascript:history.back()'>« Back</a></p>"));
	  }
	} 

);

add_filter('comment_form_defaults',function ($submit_field) {		   
		$submit_field["fields"]["author"] = $submit_field["fields"]["author"].
		'<input id="wpcookie" name="wpcookie" type="hidden" value="1"><script>
		setTimeout( () => { document.querySelector("input#wpcookie").value = "ok" } , 5000 )
		</script>';
		
return $submit_field;	
});

Bron: Redpishi.com

Geen externe API’s

Geen externe API’s: De code is stand-alone en heeft geen externe services (zoals Akismet of reCAPTCHA) nodig, wat de privacy verbetert en afhankelijkheid van derden elimineert.

Vind je dit te ingewikkeld? Dan kun je me inhuren om dit snel voor jou te implementeren. Mail even via het contactformulier. Let op: Deze code mag je vrij gebruiken ‘as is’. Het kan zijn dat jouw server een andere configuratie heeft, waardoor het bij jou niet werkt. Ik ben daar niet aansprakelijk voor.

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *