Handy WordPress tricks: Protect your email addresses from spambots

Emails have been a spam-prone channel for a while already. A common practice for spambots is to crawl webpages and search for strings that match one of the common email regular expressions. Those email addresses are then stored and used for spamming, phishing and other abuses you likely don’t enjoy being exposed to.

An easy (but not so pretty) solution

Some of us have already found a way to go around this by replacing special characters in emails with tokens, for example, the . with (dot) and @ with (at). So for example:

someone@somesite.com

would look like this:

someone(at)somesite(dot)com

However, it does make emails a bit unreadable when displayed on a page. It also creates a certain amount of discomfort for end-users, because they would have to replace those tokens manually with the corresponding character before using the email for something.

Another problem with that approach is that it’s very easy to change the regular expression to also catch tokens as (dot), (dash), (underscore), and (at). So, for such “smarter” bots, this solution simply won’t work.

WordPress to the rescue

Luckily, WordPress provides an easy-to-use but pretty convenient alternative to the above mechanism. It’s just a simple function that one could wrap their email address with: antispambot().

Funny enough, this function is older than WordPress itself. It has been part of the project since day one, as it existed in the b2/cafelog project that WordPress initially forked. This means that it is over 18 years old already!

So, how does it work? It’s actually pretty simple:

<?php

$email = 'someone@somesite.com';
echo antispambot( $email );

?>

This will obfuscate your email address by converting email addresses characters to HTML entities. Running the above code once, it produced the following output:

&#115;o&#109;&#101;&#111;&#110;e&#64;&#115;&#111;m&#101;site.c&#111;&#109;

while on the second call, it rendered:

s&#111;&#109;&#101;&#111;n&#101;&#64;so&#109;&#101;&#115;i&#116;e.&#99;&#111;m

Quite cryptic, right? That way, the email will look just right for the end-user but will be gibberish for the spambots. You’re probably curious how the function actually achieves that? Just continue reading.

Under the hood

Internally, the function will randomly decide for each character whether to obfuscate it or not. This means that each character will either end up being an HTML entity or stay unchanged. This also means that the end result will be different every time.

So for example, a may be converted to &#97; and P may be converted to &#80;.

Furthermore, if you pass 1 as the second argument, this will add another obfuscation mechanism – URL-encoding of the character, again at random. This makes the email more friendly for mailto: links:

<?php

$email = 'someone@somesite.com';
echo antispambot( $email, 1 );

?>

Don’t forget to escape it

In practice, this function will often convert most of the characters to HTML entities. In theory, though, any malicious HTML that is inserted in the email’s place could potentially render malicious code. The reason for that is the fact that each character is converted randomly, so in theory, there is a small chance (and it grows smaller as the email gets longer) that no characters will be converted at all.

So, to stay on the safe side, I’d always encourage escaping when outputting such an email:

<?php

$email = 'someone@somesite.com';
echo esc_html( antispambot( $email ) );

?>

Now you’re probably thinking: “but hey, won’t this cause double encoding because esc_html() will convert each & character to &amp?”. Well, actually, it won’t. esc_html() will act smart and will generally avoid double-encoding HTML entities. So, you can feel free to use it in conjunction with antispambot(). The same applies to other formatting functions, like esc_attr() for example.

Coda

Thank you for getting this far! I hope you find this information useful.

Got any questions or suggestions? Have a more advanced use case to share? Feel free to comment in the form below!

Leave a Reply