Best Method for Email Obfuscation?
Awhile ago, Silvan Mühlemann conducted a 1.5 year experiment whereby different approaches to email obfuscation were tested for effectiveness. Nine different methods were implemented, with each test account receiving anywhere from 1800 to zero spam emails. Here is an excerpt from the article:
When displaying an e-mail address on a website you obviously want to obfuscate it to avoid it getting harvested by spammers. But which obfuscation method is the best one? I drove a test to find out.
After reading through the article and its many findings, here are what seem to be the best methods for obfuscating email addresses displayed publicly on web pages..
Reverse the text direction
According to the article, one of the best methods for hiding your email address from spammers is to write it backwards and then reverse the text direction with a little CSS trickery. Let’s say we want to display and obfuscate the following email address:
kick@inception.com
We would include the email address by writing it backwards in our web page, and wrapping it in a <span>
tag with a nice class attribute:
<span class="obfuscate">moc.noitpecni@kcik</span>
Then to display it properly for our visitors, we apply the following CSS:
.obfuscate { unicode-bidi: bidi-override; direction: rtl; }
When CSS is enabled, this declaration block will reverse the display of any text within the .obfuscate
-classed <span>
. Works great, but not without a few downsides:
- Requires the user to manually type out the address (i.e., a
mailto:
link won’t work) - The email address will display backwards if CSS is unavailable.
- When the user does a copy/paste of the email address, it’s going to be backwards.
- Bots could probably “decipher” these strings easily if programmed to do so.
Despite these issues, the reverse-text method proved 100% effective throughout the 1.5-year test, so definitely a good method to know.
Add some “null” text
Another effective way of obfuscating email information is to insert some “dummy” text into the email address itself. For example, using our “kick@inception.com
” address, we would insert “<span>null</span>
” into the address:
<span class="obfuscate">kick@<span>null</span>inception.com</span>
..or even something more complex:
<span class="obfuscate">
kick<span>null</span>@<span>null</span>inception<span>null</span>.com
</span>
With these injected character strings, the markup looks nothing like an actual email address. But we’re not finished with it yet – we still need to ensure that our human users are able to read the correct information. This involves hiding the nonsense <span>
s with a little CSS:
.obfuscate span { display: none; }
Simple enough. Again, this works great because users will only see the email address and not the “null” text. This method is effective at hiding your email address from the spammers, but there are some familiar downsides:
- Requires the user to manually type out the address (i.e., a
mailto:
link won’t work) - The email address will display the “null” text if CSS is unavailable.
- When the user does a copy/paste of the email address, it’s going to include the “null” text.
- There may be a bot that can decipher such convoluted email addresses, so be careful.
Serious accessibility/usability challenges, but still another 100% effective method according to the test results.
Encode/Decode with ROT13/JavaScript
The ROT13-algorithm is an encoding method whereby all alphabetic characters are rotated by 13. Similarly, ROT5 is used to encrypt numeric digits, whereby every number is incremented or decremented by 5. This type of cipher is commonly used in Usenet/chat threads.
Using ROT13, we can use a free online tool (or directly via PHP) to encode an email address and then use JavaScript to decode it in the web page. Encoding our example email address, we get this:
xvpx@vaprcgvba.pbz
We then include this ROT13-encoded address in the web page using this JavaScript:
<script type="text/javascript">
document.write("<n uers=\"znvygb:xvpx@vaprcgvba.pbz\" ery=\"absbyybj\">Fraq n zrffntr</n>".replace(/[a-zA-Z]/g,
function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);}));
</script>
That snippet will then display the following markup:
<a href="mailto:kick@inception.com" rel="nofollow">Send a message</a>
..which will create an email link on the page for your visitors:
This is another 100% effective method according to the test, with the only downside being that JavaScript is required for it to work.
Other Obfuscation Methods
The test also included a fistful of other methods that varied in their overall effectiveness. Here is a quick run-down:
- Replacing “
@
” with “AT
” and “.
” with “DOT
” in plain-text email addresses was also quite effective (but not 100%). - Building/inserting the email address entirely with JavaScript (404 link removed
http://bit.ly/ImZkc6
) was the next-best method, but some spam still got through. Looks like harvesters are learning JavaScript. - Encoding “
@
” and “.
” with character entities in plain-text addresses resulted in a significant volume of spam. - Splitting the email address up with HTML comments was also ineffective at stopping spam.
- Encoding the email address with urlencode was less effective than any other method mentioned so far. Email-harvesting bots apparently have the whole “urlencode” game figured out.
- And worst of all is just using plain-text to display your email address. Definitely not recommended if you hate teh spam!
And, although it wasn’t included in the test, you could also use an image to display your email address, but the accessibility and usability is pretty poor, and there are bots that can interpret image-based text.
So which one of these email-obfuscation methods is best? One of the first three, based on the test results. Generally, these methods are useful for dropping the occasional email here and there, but perhaps the best method is to..
Use a Contact Form
When it comes to providing an easy, spam-free way for people to contact you, nothing beats the convenience of a simple, web-based email form. If you are using WordPress, there are many contact forms available, including my clean and simple Contact Form X, which is Ajax-powered for extra awesomeness.
Of course, form email has its downsides as well. Most notably, it takes longer to set up and test an online form than it does to slap down a line or two of code (as in our previous examples). Another challenging issue that I have experienced is getting contact forms to properly handle code characters (HTML, PHP, et al).
Use whatever works
If you have the time, using a web-based email form is probably the best solution for contact pages, but if you just need a way to simply include an email address, one of those first three methods may be just the ticket for keeping your publicly displayed emails spam-free.
For more information on these (and more) anti-spam email techniques, check out the original article. And, if you happen to have a favorite – and effective – email obfuscation trick, throw down in the comments and I’ll add it the post.
48 responses to “Best Method for Email Obfuscation?”
For the problem of not being able to use mailto links in your examples, how about doing something like this:
<a href="/mailto.php?email=">obfuscated email</a>
Then in the mailto.php script, just decode the email and setup the location header to an actual mailto.
Not the most elegant solution, but it hey it works.
How do you post PHP code here? Seems like mine was removed, here it is again:
<a href="/mailto.php?email=<?php echo base64_encode('someone@somewhere.com'); ?>" rel="nofollow">obfuscated email</a>
Sorry for the triple post, I’ll just post the code here: http://pastebin.com/UKjbk3fP
I usually use a contact form, but if I HAVE to display an email address on a page, I use Enkoder (http://hivelogic.com/enkoder), which has a web form and an OS X application to obfuscate emails (or anything else).
Hi Jeff,
I usually build e-mail addresses entirely with JavaScript and it looks like very efficient (as I experienced), but maybe I will give some try to your tricks. :)
Anyway, I think that the real threat is viruses and worms on clients’/customers’ PCs which are gathering the e-mails from their e-mail clients. :( It’s inevitably to protect our e-mails from them.
It requires a bit more on the usability side, but my favorite method is to use reCAPTCHA’s MailHide service.
Although, I’m unsure how truly effective it is. My address is out there enough that I get plenty of spam (Gmail blocks most of it), but I do obfuscate every now and then, especially if for some reason I’m having to publish some other e-mail address somewhere.
changing the (.) into dot and @ into at will also work
such as myname@site.com into myname(at)site(dot)com
I take the 3rd method listed in the unordered list to a deeper level. Instead of just changing the @ and . symbols into entities, I translate the complete email and “a” tag into entities, starting with the beginning bracket and ending with the closing bracket. This completely obfuscates the whole mailto link!
The most effective and accessible method to display linked e-mail addresses is to show them on a POST request only. I did this on http://ig-bkh.de/kontakt/ for example – zero spam. I wish I had done this earlier on my own site. ;) Too late now.
It seems like spammers aren’t (yet) sending POST requests. Sooner or later they’ll do of course …
@Julian: Always use example.com/org/net for examples. You may just have published a working e-mail address.
You can use anything@example.com for examples. See here http://www.rfc-editor.org/rfc/rfc2606.txt
If you use WordPress, can you use the antispambot function
http://codex.wordpress.org/Function_Reference/antispambot
And you can turn it into a shortcode
function email_obfuscation( $atts, $content = null ) {
return antispambot( $content );
}
add_shortcode( 'email', 'email_obfuscation' );
[email]youremail@example[/email]
Just noticed something odd. The comment reply notification email I received converted the [ email ] from Jesper’s comment & replaced it with the recipient email (my email).
I know the reply notification plugin has shortcodes for crafting the message boilerplates, but I wouldn’t have expected it to process those shortcodes in comment content.