play/type blog

We are creating Germany's juiciest event platform, boomloop.com. Because we love the Internet more than our own mothers. See for yourself. check out boomloop.com


01
Mar

Graceful email obfuscation in ruby on rails: hiding email adresses to beat spam bots

Here’s a little thing I wrote for this blog. You can try it out straight up: click on the contacts link on the sidebar, then on ‘send mail to rany’. This will open in your mail application with my email address, as it should.

Now turn off javascript and reload the main page. You’ll see ‘send mail to rany’ again, but this time the link will take you to http://playtype.net/contactto/new/enal+cynlglcr+arg. This is what the spam bots are going to see. Clicking here takes you to a form that forwards your message without divulging the email in question.

This technique is called ‘Graceful email obfuscation’, and you can read up about this on a list apart in this article.

This behaviour is wrapped into the graceful mailto obfuscator rails plugin. once you’ve installed this, your mail_to helper will produce obfuscated links which behave exacty like on this page. Niceness!

Requirements

Lowpro and Prototype. Lowpro enhances Prototype with some nifty unobtrusive shit. Download from dan’s svn repository. Currently that’s 0.5: http://svn.danwebb.net/external/lowpro/tags/rel_0.5/dist/lowpro.js.

Put that in /public/javascripts then include it in your application layout:

<%= javascript_include_tag "lowpro" %>

Example

Calling mail_to(“me@mail.com”, “mail me”) will generate the following link:

<a class="obfuscated" href="/contactto/new/zr+znvy+pbz">mail me</a>

For users who do not have javascript turned on, /contactto/new collects a message which can be submitted to an action which sends the email, without it ever being divulged.

When javascript is turned on, a behaviour converts the obfuscated anchor into a normal mailto: link with the orignal email address. spam bots will now bounce off your site like frustrated popcorn.

Installation

Install the plugin:

./script/plugin install http://svn.playtype.net/plugins/graceful_mailto_obfuscator/

Then add the following lines to your application.js:

Event.addBehavior({
  "a.obfuscated": EmailDecoder
});

Include the EmailDecoder behaviour in page head:

<%= javascript_include_tag "email_decoder" %>

Graceful Degradation

Now you’ll need something to handle /contactto/new for those people who are not using javascript. the easiest thing is to have a textarea here for the message. when submitted, the server sends the email ob behalf of the user, without ever divulging the email address. here’s how to do this:

  1. create a form that takes a message and passes param[:email] along to the create action after a submit.
  2. inside create, decode the email like this: email = Loopy::EmailObfuscator.decode_email(CGI.escape(params[:email]))
  3. send an email to this address from the server.

Done!

Comments

There are 3 Comments for this post.  Write comment →

Hi,

For my community site http://www.hightechcville.com I am aggregating lots of information, including email addresses about people! Now, I know some people will be concerned about spam bots using this site as a place to suck in email addresses, so your plugin comes out at the perfect time for me!

One bug report is that if you include the :defaults javascripts:

then you get a javascript error because the behavior you added to application.js is loaded before the lowpro javascript file. If I move lowpro higher up, then it complans because prototype hasn’t been loaded yet. I added a little behaviors.js to load after email_decoder, and that solved the issue:

Thanks for the plugin!

Hi,

I found a bug! Some emails don’t encode/decode properly, so I put in a quick check in the plugin:

def mail_to_with_graceful_obfuscation(args)
mailto = mail_to_without_graceful_obfuscation(
args)
match, email = mailto.match(/mailto:(.)"/)
end
  1. check that the obfuscate/decode process works, with some emails it doesn’t
    if email == Loopy::EmailObfuscator.decode_email(Loopy::EmailObfuscator.obfuscate_email(email))
    mailto.gsub! “mailto:”, ”/contactto\/new/”
    mailto.gsub! /^<a /, ”<a class=\”obfuscated\” ”
    mailto.gsub! email, Loopy::EmailObfuscator.obfuscate_email(email)
    end
    mailto

A good example of an email address is David.Canning@PatternFall.com. If I downcase it, the encode/decode works better, but the ”.” in the email seems to still mess it up. Hope this helps.

I have piston importing this plugin, so I’ll keep an eye on it. I like having a CHANGELOG or CHANGES file in the plugins to help tell what has changed in the plugin.

Hey Eric,

thanks for posting the bug :). I think I’ll move my plugins to github so that people can work on them more easily. In the meantime, I’ll add your patch to the project.

Cheers!

Write a comment

Required in bold.