Transparent email obfuscation to prevent SPAM

Permalink
I have been looking for a way to obfuscate all email addesses automatically that are contained inside a content block. After some research I ended up with this custom template. To install it just save as blocks/content/view.php .
<?php 
   defined('C5_EXECUTE') or die("Access Denied.");
   $content = $controller->getContent();
   // Obfuscate email addresses in href links
   $content = preg_replace_callback('/(<a[^>]*href=")(mailto:)([^"]+)/',create_function('$matches','return $matches[1] . "NOSPAM:" . strrev($matches[3]);'),$content);
   // Obfuscate email adresses in text
   // found athttps://pureform.wordpress.com/2008/01/04/matching-a-word-characters...
   $content = preg_replace_callback('/\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]+\b(?!([^<]+)?>)/i', create_function('$matches','return "<span style=\"unicode-bidi:bidi-override; direction: rtl;\" class=\"transparent-email-obfuscation-unreverse\">" . strrev($matches[0]) . "</span>";'),$content);
   print $content;
?>
<script>
// restore mailto: links
$("a[href^='NOSPAM:']").each(function(){
   var email = $(this).attr("href").substr(7);
   email = email.split("").reverse().join("");

What it does is basically replace all email addresses with their reversed version. So "me@myself.com" will become "moc.flesym@em". In addition to that for href-contained addresses the "mailto:" will replaced with "NOSPAM:" and other addresses will be wrapped in a span tag that gives the browser instruction to render from right to left (direction: rtl).
On the client side all of these changes will be reversed using javascript. So the end-result looks identical to the original version.

What do you think of this method? Any comments or suggestions are apprechiated.

I also wrapped this in a package and submitted it to the marketplace where it might be approved soon.

EDIT: The Add-On is available now:http://www.concrete5.org/marketplace/addons/transparent-email-obfus...

PatrickHeck
 
Shotster replied on at Permalink Reply
Shotster
Nice approach intercepting the content in the view template, Patrick. If you're looking for something much more robust, however - i.e. encryption as opposed to simple (and easily foiled) obfuscation - you might want to check out...

http://www.concrete5.org/marketplace/addons/encrypted-e-mail-addres...

It has a simple API call which you invoke to encrypt an address. In other words, you wouldn't need to use the block UI. You would instead use the API for programmatic access to the encryption algorithm. Thus, you could use a similar approach to find the email addresses, encrypt them, and then replace the addresses with the encrypted output.

In fact, I think I'm going to do that myself. Thanks for pointing me in that direction!

Regards,

-Steve
Shotster replied on at Permalink Reply
Shotster
One other thing to note with your approach, Patrick, is that if there are multiple content blocks on a page (which is VERY common on my clients' sites), then your JS code will be output for each one. That means the client-side de-obfuscation code will be needlessly executed multiple times. Now, it's probably not a big deal from a performance standpoint, but a more elegantly crafted solution would separate the de-obfuscation code into a separate JS library file that would be included once per page.

Anyway, just some feedback FWIW.

-Steve
Mnkras replied on at Permalink Reply
Mnkras
I have a fully automatic way that does it on every page and every block, it just requires concrete 5.4.2 (in alpha) I can setup a demo if someone wants to see it.

Mike
Shotster replied on at Permalink Reply
Shotster
Sounds great! Does it intercept the output in view.php by chance - like the optimizer mod? That seems like a good way to go if you wanted to catch everything.

-Steve
Shotster replied on at Permalink Reply
Shotster
In fact, I just got to thinking that it would be nice to have an on_before_output event to hook into. I haven't been keeping up with the alpha, so maybe that's what's been done?

-Steve
Mnkras replied on at Permalink Reply
Mnkras
Thats exactly what I added :P I havnt tested what happens when the event is
accessed multiple times, but I know it works fine with only 1 thing
accessing it.

Mine uses reCAPTCHA mail hide api to hide emails btw

Mike
On Jul 17, 2011 6:18 PM, "Concrete5 Community" <discussions@concretecms.com>
wrote:
Shotster replied on at Permalink Reply
Shotster
> Thats exactly what I added

Sweet!

> Mine uses reCAPTCHA mail hide api to hide emails btw

Bummer! (I hate those things.)

:-/

-Steve
PatrickHeck replied on at Permalink Reply
PatrickHeck
You're right about the JS Steve, it should be in a place where it's only executed once for performance reasons. To be completely honest I only implemented it this way because I was not really sure where to put it when I wrap it in a package. Would that be the packages/mypackage/blocks/content/js/ directory with a addheaderitem call in the packages/mypackage/blocks/content/controller.php ?

I agree that encryption should deliver a better SPAM protection than just obfuscation. On the other hand the big advantage is that there is a fallback available if javascript is not activated.
Shotster replied on at Permalink Reply
Shotster
> Would that be the packages/mypackage/blocks/content/js/ directory

No, it should go in the package's root (/mypackage/js/).


> with a addheaderitem call in the packages/mypackage/blocks/content/controller.php?

Yes, something like...

$hh = Loader::helper('html');
$this->addHeaderItem($hh->javascript('myjscode.js', 'my_package_handle'));



> the big advantage is that there is a fallback available if javascript is not activated.

I'm not quite understanding the fallback, unless you're saying that forcing the user to perform mental gymnastics is an acceptable fallback. :-/

-Steve
PatrickHeck replied on at Permalink Reply
PatrickHeck
Well,
me@myself.com

will become
<span style="unicode-bidi:bidi-override; direction: rtl;">moc.flesym@em</span>


And that still displays the same in the browers because it's rendered as a right-to-left language. It's not my own idea though - found it at
http://www.muehlemann.com/2008/07/20/ten-methods-to-obfuscate-e-mai...
PatrickHeck replied on at Permalink Best Answer Reply
PatrickHeck
My recommended method to use this is the Automatic Email Obfuscator Add-On:
http://www.concrete5.org/marketplace/addons/automatic-email-obfusca...
You just install it once and it automatically deals with every email address in the site.