The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mojolicious::Plugin::TagHelpers::MailToChiffre - Obfuscate Email Addresses in Templates

SYNOPSIS

  use Mojolicious::Lite;

  plugin 'TagHelpers::MailToChiffre' => {
    pattern_rotate => 720
  };

  # Path to index page
  get '/' => 'index';

  # Add fallback for non-JavaScript users
  get('/contactme')->mail_to_chiffre(cb => sub {
    my $c = shift;
    # Of course - don't display it this way:
    $c->render(text => 'You tried to ' . $c->stash('mail_to_chiffre')->to_string);
  });

  app->start;

  __DATA__
  @@ layouts/default.html.ep
  <!DOCTYPE html>
  <html>
    <head>
      <title><%= title %></title>
      %# Add javascript and stylesheet information
      <%= javascript begin %><%= mail_to_chiffre_js %><% end %>
      <%= stylesheet begin %><%= mail_to_chiffre_css %><% end %>
    </head>
    <body><%= content %></body>
  </html>

  @@ index.html.ep
  % layout 'default', title => 'Welcome';
  <p>
    Mail me at <%= mail_to_chiffre 'akron@sojolicious.example', subject => 'Hi!' %>
    or
    <%= mail_to_chiffre 'test@sojolicious.example', begin %>Write me<% end %>
  </p>

DESCRIPTION

Mojolicious::Plugin::TagHelpers::MailToChiffre is a Mojolicious plugin helping you to obfuscate email adresses visible on your website to make it less easy for spam bots to grab them.

It uses JavaScript to obfuscate mailto-links (while providing a fallback option for users without JavaScript) and in case you want to show the email address in plain text it is obfuscated using CSS. Although modern spam bots may be capable of parsing and executing JavaScript and interpreting CSS, it is more likely, that they don't try to do it, as it takes time and power better be invested in sites with less protected emails. This is just my assumption for the moment - it may not held entirely true. The idea is to make the obfuscation easy for modern browser and expensive for spam bots, by making it necessary to parse and execute CSS and JavaScript without giving too much hints, that this is necessary to deobfuscate email addresses (i.e. not creating too obvious patterns for the obfuscation, so in case a spambot programmer knows this scheme it is more expensive to search for than simply scan for an email pattern using a regular expression).

This plugin is not useful for obfuscating millions of email addresses on your site, as once a bot has adapted the scheme and your parameters, parsing and deobfuscating is rather trivial.

The plugin supports utf-8 domain names, utf-8 usernames and tries to be compatible with RFC2368, including obfuscated to, cc and bcc addresses.

Please be aware of the environment you use email obfuscation in and make sure your human visitors will always be able to deobfuscate your address! And please keep in mind that it's arguable if email obfuscation is useful at all (see pro and contra).

Mailto Obfuscation

The mailto obfuscation merely follows the basic principle of this alistapart.com article. The mailto-link is build using JavaScript with information stored in a harmless looking http-URL. Instead of a simple rot13 obfuscation, the obfuscation uses a XOR operation on a rotating public One Time Pad, a variable character shift, and afterwards applys an ASCII encoding scheme on the result (similar to base64; currently using rot13 for alphanumericals and a cheap ordinal number print for all other characters - a scheme likely to be changed).

Using the One Time Pad guarantees that all email addresses look different each time they are obfuscated to make it harder to leave a simple pattern for finding these strings (especially the recurring domain part).

The character shift with a variable number of characters makes it necessary to parse the JavaScript, even if the spambot knows the scheme and the obfuscated URL.

The JavaScript method name can be set manually, otherwise it defaults to a random string.

Display Obfuscation

In case you want to make the email address visual, it is obfuscated using CSS with reversed directionality and non-displayed span segments.

Although the left string tries to not leave too many hints of its email address nature, this obfuscation is obviously easier to deobfuscate than the javascript obfuscation, i.e. less protected.

METHODS

Mojolicious::Plugin::TagHelpers::MailToChiffre inherits all methods from Mojolicious::Plugin and implements the following new ones.

register

  # Mojolicious
  $app->plugin('TagHelpers::MailToChiffre');

  # Mojolicious::Lite
  plugin 'TagHelpers::MailToChiffre' => {
    method_name => 'deobfuscate',
    pattern_rotate => 720
  };

Called when registering the plugin. Accepts the attributes method_name and pattern_rotate.

The method_name is the name of the JavaScript function called to deobfuscate your email addresses. It defaults to a random string. The pattern_rotate numeral value will rotate the characters of the obfuscated email address and is stored directly in the javascript. It default to 2. The no_inline removes the onclick parameter from the "mail_to_chiffre" link and establishes an eventhandler on all "mail_to_chiffre" links on a single page. This is required to make the helper compliant to Content Security Policy.

All parameters can be set either on registration or as part of the configuration file with the key TagHelpers-MailToChiffre.

HELPERS

mail_to_chiffre

  # In Templates
  <%= mail_to_chiffre 'akron@sojolicious.example', subject => 'Hello!' %>
  <%= mail_to_chiffre 'akron@sojolicious.example', cc => 'metoo@sojolicious.example' %>
  %= mail_to_chiffre 'akron@sojolicious.example' => begin
    <img src="mailme.gif" />
  % end

Creates an anchor link with the resulting obfuscated email address (i.e. the fallback path defined by the shortcut). Accepts an email address and further query parameters of the mailto-link as defined in RFC2368. Multiple values can be denoted using an array reference (e.g. to and cc). to, cc and bcc links are obfuscated, too.

In case the helper embeds further HTML, this is used for the link content, otherwise the first email address is used obfuscated as the link text.

mail_to_chiffre_css

  # In Templates
  <%= stylesheet begin %><%= mail_to_chiffre_css %><% end %>

Returns the deobfuscating CSS code.

mail_to_chiffre_js

  # In Templates
  <%= javascript begin %><%= mail_to_chiffre_js %><% end %>

Returns the deobfuscating JavaScript code.

SHORTCUTS

mail_to_chiffre

  # Mojolicious
  my $r = $app->routes;
  $r->any('/contactme')->mail_to_chiffre('Mail#capture');

  # Mojolicious::Lite
  any('/contactme')->mail_to_chiffre(
    cb => sub {
      # ...
      # The plain mailto-link is as a Mojo::URL object
      # stored in the stash value 'mail_to_chiffre'
    }
  );

Define the URL prefix for the obfuscated anchor link, which also serves as the fallback path for users without JavaScript. Accepts all parameters of "to" in Mojolicious::Routes::Route. The plain mailto-link is present as a Mojo::URL in the stash value mail_to_chiffre.

You can present a security question or a capture before you relocate the user to the deobfuscated mailto-link, or you may provide an email form instead.

The fallback response will contain a header to ban search engines.

KNOWN BUGS AND LIMITATIONS

This plugin works best in a demon environment (and worse in a CGI environment). The output may change in further versions, which means the CSS and JavaScript files (in case they are external) may have to be updated.

DEPENDENCIES

Mojolicious, Mojolicious::Plugin::Util::RandomString.

AVAILABILITY

  https://github.com/Akron/Mojolicious-Plugin-TagHelpers-MailToChiffre

COPYRIGHT AND LICENSE

Copyright (C) 2014-2021, Nils Diewald.

This program is free software, you can redistribute it and/or modify it under the same terms as Perl.