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 .
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...
<?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("");
Viewing 15 lines of 22 lines. View entire code block.
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...
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
Anyway, just some feedback FWIW.
-Steve
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
Mike
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
-Steve
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
-Steve
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:
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:
> Thats exactly what I added
Sweet!
> Mine uses reCAPTCHA mail hide api to hide emails btw
Bummer! (I hate those things.)
:-/
-Steve
Sweet!
> Mine uses reCAPTCHA mail hide api to hide emails btw
Bummer! (I hate those things.)
:-/
-Steve
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.
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.
> 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...
> 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
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
Well,
will become
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...
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...
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.
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.
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