Best Method for Email Obfuscation?
Posted on August 1, 2010 in Accessibility, Function by Jeff Starr
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 an online tool (or 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 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 Coldform. Non-WordPress users also enjoy a virtual cornucopia of email-form options, including some sweet Ajax-inspired stuff.
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.
Related articles
- Spamless Email Address via JavaScript
- Industrial-Strength Spamless Email Links
- WordPress Hack: Multiple Email Recipients for Contact Coldform
- WordPress Tip: Update Email Address in the WordPress Database
- Invite Only: Visitor Exclusivity via the Opt-In Method
- New and Improved JavaScript Clock
- Auto-Focus Form Elements with JavaScript
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.
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
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.
@Aziz Light: Absolutely. Hivelogic Enkoder is a great way to go. I have used the online service many times and highly recommend. Good call.
@Sunny Singh: Nice tip! Looks like that may be the ticket for base64-encoding while using the
mailtolink. Thanks for sharing. Btw, for future reference, to post code in your comments, just wrap each line or term with a set of<code>tags. WordPress just gobbles the stuff up otherwise.@Rick Beckman: Thanks for mentioning the captcha method. Using reCAPTCHA’s MailHide or any other captcha method is known to be pretty effective. Some contact forms even have this functionality built-in, making it even easier. Good to see you again, btw – you’ve been keeping a rather low profile! :)
@Julian: Yes definitely, and that method is mentioned in the article in the “Other Obfuscation Methods” section. Apparently it’s a pretty effective method.
@Micah: Sweet tip! I may try that method for my next project. Would be great to get the protection of email info while also using the
mailtolink. Nice.@Thomas Scholz: Always great stuff from you! Filtering by POST request seems like it would be effective indeed. What fallback do you recommend once spammers catch on and start POSTing their requests?
@AC: Good point. This was something that I was wrong about for years. At some point way back in the day, it seems that
example.comet al were not reserved for such use. Good to know that it’s okay to use.@Jesper: That’s another useful method, but I’m not sure how effective it is.. I recall using the
antispambotfunction back in early WordPress days and receiving tons of spam email shortly thereafter.@Rick Beckman: That is interesting indeed.. keep in mind that Perishable Press is running a (much) older version of WordPress, so that shortcode processing in comments may not happen in newer versions.
(Not trying to change the subject…)
I have a question that stems from this article:
Do you think the backwards method (with CSS to display the address forward) could possibly work for a very simple CAPTCHA system? The bots would see the digits/letters forward(the invalid input) The users would see the backward(valid input) display?
Nice article!
@Jeff: I’ve added a text field and hid it per CSS. If it isn’t empty, I return nothing.
An additional option were: encode the IP address of the visitor per base49 (anything from 20 to 64 will do) in the local part of the e-mail address and use a catch all mail account. That could be the base of a very useful shared block file. :)
But in the long term … e-mail is dead.
@Thomas: No way is email dead - we’ll be gone long before email, unless you’re talking about IMAP/SMTP technology, which may be left for something better.
There is a practicality, utility, and simplicity with email.
What would replace it?
Facebook messages are the future, Jeff. ;)
Seriously, though, even the mighty Google sought to “upgrade” email with Wave, but from what I can tell, it pretty much flopped.
@Jeff: E-mail as a format is (without encryption) insecure, it offers poor accessibility and no build in protection from spammers (who produce more than 80% of all e-mail traffic).
As a plain text medium it cannot handle binary files very good. And a conversation with more than two addressees (sp?) is ridiculous difficult for the average user.
Okay, maybe these are the reasons why we stay with it. :)
@Rick: Yes, Wave was very promising, but it’s dead (for the moment). Google seems to have a secret recipe for failing with social apps (bookmarks, buzz, chat, video). Let’s hope Yahoo! doesn’t find out this …
Maybe e-mail will die without a replacement. I’m eager to see what happens then. At least we don’t have to worry about these kind of spammers anymore.
@Rick: lol - so true! Facebook is definitely the answer. ;)
@Thomas: I agree that the technology will/should change, but the utility of the email as communicative tool will be around until the end of time. It’s just too practical for the all-purpose functionality it provides. Google Wave was a flop because you can’t do better than dead-simple.
As for the technology behind, I’ve been emailing stuff for years with no major problems regarding security, accessibility, or binary content. Or, at least no more problems than any other software.
For multiple-thread/person conversations, however, I agree that email isn’t the future. :)
Thanks for this overview. I usually use submittable forms, but just acquired a client who doesn’t like them. This info helped me figure out what to do.
I ended up using the ROT13/JAVASCRIPT, but I used ROT47 instead, and encoded my email address and phone number.
I saw another method on a site - http://www.albionresearch.com/misc/obfuscator.php.
Is that better, or worse, then the ROT/JS method?
Since the ’90’s I was using Jim Tucek’s encoder script which eventually disappeared. Now Dan Appleman picked it up and made it available for everyone again. Zero spam over the course of 12 years. It gives you a variety of visitor clickable mailto: links decoded via javascript and handles any reasonable number of different email addresses per site. It’s still free too. It works on Wordpress or plain old html sites.
It’s at http://www.danappleman.com/?page_id=61
My favoured obfuscation method is to simply use a spam email address combined with a straightforward encoder , eg
greetings@mysite.comWhen the spam gets too much, just change the email address to eg
helloagain@mysite.comThanks for this thorought investigation. I recently had to setup a wordpress for my school, with many authors that i could not expect to behave correctly. I therefore set up a plugin that turns any email address in the post body into an obfuscated html string à la : john(replace this parenthisis by the @ sign)doe.com, so the html is clean and users without javascript can figure out the email address quite easily. With a bit of javascript i transform it into a nice mailto: link.
If you’re interested, you can find it here.
http://pixeline.be/blog/email-protector-wordpress-plugin
PS: really enjoyed that article on htaccess php error logging. Great write up!
Or you could just use a URL shortener like http://gi.vc/ to shorten your email address and put that on the internet. I don’t know how effective it would be, but how many spam bits would follow URLs to see if they are email addresses?
@Blake Embrey: Interesting idea – I may try this on an upcoming project. Thanks for sharing :)
Not just great article but great site and very usefull tips.
Just a small addon on email obfuscation methods.
On some sites I made a small flash file with the email address, containing button with full mailto:… link. Graphicaly, it is not problem to fully simulate look and feel of the context around email (regarding font).
Even though not a 100% fool proof idea, I use a mixture of PHP and it’s GD library to create a script which allows me to hotlink basically to using a GET param which is the email base64 encoded, which then returns an image with the decoded text.
The only downside being uses more resources also some of the more clever bots can read images, so you could always try going the way Captcha’s do by distorting the image, but again still not 100% safe but then again nothing ever is.
Could be interesting to see what people come up with in the next couple of years, perhaps a nifty little script that opens your default mail client and inputs the email into the “to” section you never know.
Ps: Great post thanks.
So– how to put the cat back in the bag?? I am constantly getting new clients that have for years left their primary business contact in the clear–and now they want me to try to cut down on the spam.
Usually, I just tell them the move to Gmail (really good spam filter), but I’ve wondered if you obfuscate an email that is in the wild already is it a waste of time or should you just do it and perhaps in a few years the spam will die down…
Of course it’s best to convince them to abandon the address, and use one of the solutions presented here on a new address.
Anyone else figured out a better way to deal with this?
I would NOT recommend REVERSE THE TEXT DIRECTION method because I always copy and paste email addresses if I want to email them something. If they copy and paste and it reverses on paste, they will NOT know it’s invalid. That’s why you get ZERO email… they wouldn’t know it’s invalid once they paste it in email address and send it only to be told it’s undeliverable and that means they think you’re not doing a good job.
I like the backwards approach, but the copy-and-paste draw back is too annoying to use it. I listed some techniques on my blog and would be interested to hear what you think: http://www.alecjacobson.com/weblog/?p=1408
My conclusion was to use javascript just in time (when the user hovers over the link) that way mailto and copy-and-paste still work.
How did you test the effectiveness of these?
Here’s an online ROT13 encoder/decoder for PHP that takes all of the legwork, err, fingerwork out of it: http://rot13-encoder-decoder.waraxe.us/
Rot13 is great, but it has it’s limitations as it accepts only ascii characters. I recommend base64 encoding. It gives you a nice and compact string that can be decoded using javascript. I wrote a PHP function / jQuery plugin at http://www.php-ease.com/functions/email_link.html that accomplishes this very purpose.
Here is a simplified version of the serverside function I use, which seems to be pretty effective. It works for form felds as well. It is in semicode, not actual code:
function spoofField( ArgIn)
user_agent=request(useragent)
spoofField=argIn
‘ validator : Validators
‘ bot,crawler,http:// : search engine bots and other (usually) good bots
‘ Java : Harvester bots
‘ Urllib : SQL injectors/scrapers
if strings “http://”,”bot,crawler”,”validator”,”java”,”urllib”) is NOT in user_agent Then exit function
if string “mailto:” is in ArgIn then
spoofField=”MyFakeEmail@fakeDomain.com”
exit function
else if string “http://” is in ArgIn Then
spoofField=”MyFakeURL” (I use this for my own honeypot in action attribut)
exit function
else
spoofField=random, gibberish string
end if
end function
You use it directly in your serverside code/HTML by for example:
Here is my <a href=”">Email address
or
<form method=”post” action=”" />
or
<input type=”text” name=”" />
The real script is a bit more complicated, because I have a link to my contact formular as well as a fallback for the email address (among other things), but this is the basics. It can spoof any form field/action field and any email address, and will hide those from search engines as well as validators and scraper bots. Legit users will see the real address and form fields, others will not.
Since it is serverside, it is not relying on the user having Javascript turned on.
TIP: Lots of useragents that claims to be IE6 are in fact scraper bots. I have the algorithm for testing this as well (the user agent itself is obviously not enough), but if you implement a fallback, you can test for user agent IE6 and GZIP not accepted, then it is a scraper bot 99.9% chance. Same with Win95, Win98, IE5 and IE5.5.
Hmmm… not encoding those HTML special chars, I see :)
Hey Rune,
I blame it on WordPress! :P
That looks like some great code though, so if you’ll send me a new copy via email (to jeff at this domain), I can format and replace in your previous comment.
Thanks :)
Excellent article. Great to see someone test out different methods for results. We personally stick with contact forms and never had a problem.
A few years ago I came across a technique that I’ve used since.
While it is another JavaScript dependent solution, I haven’t yet found a better solution (other than a contact form):
http://www.maurits.vdschee.nl/php_hide_email/
Our method is to use .jpg files for each email address. But that is not for the faint of heart! Your methods are much simpler, of course. Our method requires an image editor. And it is a bit cumbersome to place on a web page. But I can tell you this. The email addresses have not been spammed in 10 years on the web. (It helps not to use the email address online in any web page.) I think your methods would work equally well, because I use text obfuscation on my blog, like email[at]yahoo[dot]com, and that email address has not been harvested, either. I think harvesters are not especially bright and probably just about all the methods work well. The most valuable email addresses will be for clueless users, more likely to click on an emailed link.
I sometimes use images for the email address but contact forms work well for me and reduce spam. I had problems when using null to confuse the code, as people would copy and paste the address without looking at it.
I have used Hivelogic EnKoder for since 2003. Its magic. However ive recently had issues using it with my CMS.
It still works magic for most situations and does an excellent job.
On recently reviewing my email hiding techniques, i came across Obfucatr http://obfuscatr.flashbit.net/obfuscate.html
This provides an active link with your email address onscreen, with the address concealed and hidden at source level.
I can only think that your email address could be scraped by copying and pasting the text onscreen. Which i thought would be a pain in a$$ in most situations. and not doable by bots.
Your thoughts to this?
Thanks for the link! :)
It looks like a solid JavaScript menthod, but I’ve heard of bots that are now able to scrape JavaScript links. Also, requires JavaScript, which isn’t that big of a deal anymore, but not everyone has it, so not recommended for more serious sites.
Interesting article, interesting comments.
BUT utterly unconvincing.
All the “solutions” provided have unacceptable accessibility and/or usability faults. Use them if you will, but never claim compliance to WCAG/508 or any other accessibility standard or code, if you should do so.
Perhaps obfustication as an image file would be acceptable, provided that an audio file were also provided for those for whom the image file was inaccessible, coupled with provision of plain text by javascript for the convenience of the 95% who are able-bodied, sighted and have enabled/not disabled javascript.
Even were someone to walk that extra mile and provide genuinely accessible and usable mail obfustication, it would be still be beaten in the end by the (chain of expletives deleted) barbarians.
Tighten up your firewalls and filters on the server and tolerate the occasional spam that does slip through.
If you get zero spam, perhaps you’re missing loads of genuine mail that people didn’t send in the end, because your obfustication defeated them?
Ultimately email protocols need authenticated senders and receivers, encryption and secure, tamper and spy-proof transmission. But with all the vested interests, I’m not holding my breath.
LOL - relax Paul, nobody is gonna falsify WCAG/508 compliance without consulting you first!
Thanks for the laugh.
Jeff,
The point is genuine.
All the methods stated here prevent or obstruct different groups of genuine readers from obtaining or using an email address from a site that uses these methods.
If you wish to take such a dismissive tone towards genuine concerns, why bother providing a comment form? Sorry for having wasted my time and yours.
Paul,
I find your concern to be right, and justified.
My technique makes screen readers provide a very reasonable experience. It replaces the email mailto: link by html that explains how to reconstruct the email address:
info(replace these parenthesis by @)pixeline.beJavascript then kicks in and produces a mailto: link.
Let me know if you think it is good or if i should update the script to better accommodate disabled users.
http://pixeline.be/downloads/email-protector-plugin-for-wordpress-450.htmlSorry didn’t mean to hurt any feelings, just thought you were having fun with that first part.. I stand corrected.
Sorry, Jeff, I guess humour and tongue in cheek doesn’t always work on the net. I guess that’s what smileys are for. Offence unconditionally untaken!