Stop spammer email harvesters by inserting addresses with JavaScript or CSS

Technologies: CSS 2+, JavaScript 1.7+

Email harvesters (spambots) scan your web pages for email addresses to add to spam mailing lists. Keep your address away from them by using JavaScript or CSS to insert your address after the web page has loaded into a visitor’s web browser. The harvester tests reported in this article show that harvesters do not run JavaScript or handle CSS styling, so they won’t find your address.

This article is part of a series on Effective methods to protect email addresses from spammers that compares and tests 50 ways to protect email addresses published on a web site.

How to insert an email address using JavaScript or CSS

Spammers use email harvesters (“spam robots” or “spambots”) to scan web pages looking for email addresses. Unlike a web browser, harvesters do not interpret the HTML and CSS that builds a page, or run its embedded JavaScript. They just look at the text of a page. You can use this to your advantage by using JavaScript or CSS to insert your email address into the page dynamically, after the page has loaded. This protects your address by keeping it out of the text portion of a page. And if harvesters can’t find your address, they can’t add it to mailing lists and you’ll get less spam.

Below I discuss each of the most common ways to use JavaScript and CSS to insert email addresses into a web page. After this list, I report the results of running pages using inserted addresses past a collection of email harvesters to see which methods are effective at protecting your address, and which are not.

Use JavaScript to insert an email address

JavaScript scripts can create and alter page content when the visitor clicks on things, or as a page is first loaded into their browser. By calling the “document.write” method, a script can write text into the page. You can use this to insert an email address (or any text) as the page is loaded. For the site visitor, the page shown in their web browser looks complete and includes your protected email address. For spammer email harvesters, which never run the JavaScript script, the email address is missing.

While harvesters do not execute JavaScript scripts, they do scan the text of the script. If your email address is clearly visible within the script, it will be harvested. So, break up the address by storing it in separate JavaScript variables. Assemble the address as it is being written to the page.

HTML <script type="text/javascript">
var email = "person";
var domain = "example.com";
document.write(email + "@" + domain);
</script>
Result

Use JavaScript to unobfuscate and insert an email address

If splitting an email address into separate JavaScript variables is not enough, you can obfuscate (a.k.a. “munge” or “encode”) it by representing it as unicode, a numeric code that assigns a unique number to each character. For instance, the letter “a” is a unicode “\u0061” in JavaScript. Browsers will execute the JavaScript script, convert the unicode back into a normal character, and show a readable email address. Spammer harvesters that cannot read unicode will not find the protected email address.

HTML <script type="text/javascript">
document.write(
'\u0070\u0065\u0072\u0073\u006f\u006e\u0040\u0065\u0078
\u0061\u006d\u0070\u006c\u0065\u002e\u0063\u006f\u006d')
</script>
Result

CodeHouse.com’s E-mail Obfuscator web page includes a free converter that generates a JavaScript script like that above. Their version also creates a “mailto” link for the email address. Just copy and paste from their web page into yours and it will work.

Use JavaScript to decrypt and insert an email address

Character code obfuscation can be decoded by some email harvesters. To better block them, encrypt an email address, then use a JavaScript script to decrypt and insert it into the page. Unless a spammer’s email harvester knows the decryption algorithm (and that is very unlikely), it won’t be able to extract the protected email address.

HTML <script type='text/javascript'>
var v2="5RNBNZCUXFKJ6XGRGA";
var v7=unescape("E7%3C1%214%030%20%27%26%3AZ%3Di1%28%2C");
var v5=v2.length;
var v1="";
for(var v4=0;v4<v5;v4++) {
   v1+=String.fromCharCode(v2.charCodeAt(v4)^v7.charCodeAt(v4));
}
document.write(v1);
</script>
Result

Syronex.com’s Anti-Spam Solutions web page has a free converter that generates a JavaScript script like that above. Their version also provides a “mailto” link for the email address. Automatic Labs’ Enkoder is an even more involved approach.  In both cases, just copy and paste from their web page into yours.

Use JavaScript to pattern replace and insert an email address

Using unicode character codes or encryption, like those above, makes it awkward to change a protected email address. You have to go back to the web site that created the script for you, re-create it with the new address, then pasted it back into your web page. Instead, you can use a simpler pseudo-encryption that embeds junk characters within the email address. Then use the JavaScript “replace” method to automatically remove those junk characters before the address is inserted into the page. Since email harvesters won’t know which characters to replace, they can’t get the protected email address. But since you do know which characters are junk, you can easily edit the address.

This example uses “_” characters that are removed by the “replace” method. The characters could be anything.

HTML <script type='text/javascript'>
document.write('p_e__r_so_n@_ex_ample_.com'.replace(/_/g,''));
</script>
Result

Use AJAX to retrieve and insert an email address

AJAX stands for “Asynchronous JavaScript and XML.” It’s a technique in which JavaScript scripts embedded on a web page query a web server for data which the script then inserts back into the web page. To hide an email address, you can use AJAX to get the address from the server. Since the protected email address does not exist in any form within the downloaded web page, spammer harvesters can’t find it.

HTML <span id="ajaxemail"></span>
<script type="text/javascript">
  var req;
  try { req = new XMLHttpRequest( ); }
  catch (e) { try { req = new ActiveXObject( "Msxml2.XMLHTTP" ); }
  catch (e) { try { req = new ActiveXObject( "Microsoft.XMLHTTP" ); }
  catch (e) { req = false; } } }
  if ( req != false ) {
    req.open( "GET", "ajaxemail.php", true );
    req.onreadystatechange = function() {
    if ( req.readyState == 4 ) {
      document.getElementById( 'ajaxemail' ).appendChild(
      document.createTextNode( req.responseText ) );
    }
  }
  req.send( null );
}</script>
PHP <?php
  header( 'Content-type: text/plain' );
  echo 'person@example.com';
?>

W3schools.com has a good AJAX Tutorial. The server-side script is PHP in this example, but it can be ASP, Perl, Java, C, or whatever. Its job is to return a text email address. In this example, it always returns “person@example.com”. The example could be extended to use an argument sent by the web page to select which email address to return.

Use CSS to insert an email address

CSS 2 defines a “content” property that inserts new text into a page wherever the style is used. You can use this to insert an email address when a page is loaded and styled. Spammer email harvesters do not understand CSS and will not insert the text. However, harvesters can read the text of a CSS file (even if they don’t understand it) so break up the email address and insert it in two steps.

HTML <span class="email"></span>
CSS .email:before { content: "person@"; }
.email:after { content: "example.com"; }
Result

TheDepot2’s Spider stomping 2k6 web page has more discussion about his method to protect email addresses.

Most current web browsers support this feature of CSS. Unfortunately, Internet Explorer 7 does not.

Results

I tested 23 widely-available email harvesters to see how well these methods work to protect an email address.  Each harvester was aimed at a test page containing plain email addresses and those inserted by JavaScript or CSS. In the table below, a harvester gets a check mark if it recognizes the protected address.

All of the harvesters were tested on Windows XP SP2. The names of the harvesters are intentionally left off to avoid giving this web page search engine attention for spammers looking for the ”best” harvester to download.

Protected email address test results
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Plain email address
Use JavaScript to insert an email address                                              
Use JavaScript to unobfuscate and insert an email address                                              
Use JavaScript to decrypt and insert an email address                                              
Use JavaScript to pattern replace and insert an email address                                              
Use AJAX to retrieve and insert an email address                                              
Use CSS to insert an email address                                              

Of course, every harvester found the plain email address that was not protected.

None of the harvesters found any of the protected email addresses inserted with JavaScript or CSS.

While most of the harvesters found the protected email address in the pattern replace method, none of them executed the JavaScript to remove the junk characters. This left the address invalid and unusable.

Conclusions

Current spambots do not execute JavaScript scripts. Doing so is possible, but it would slow down their harvesting. With so many unprotected email addresses easily available with simple harvesting, there isn’t much need yet for spammers to bother with JavaScript support. Until there is, protecting an email address by using JavaScript text insertion is an effective way to stop email harvesters and reduce spam.

There is one possible exception. The method that used unicode to obfuscate an email address in a JavaScript variable assumes that harvesters cannot decode unicode. While none do yet, several do decode similar character codes used in HTML and URLs. Adding unicode decoding is an easy and likely upgrade. JavaScript obfuscation using unicode is probably not effective for long.

During testing I was very surprised when one harvester found the AJAX protected email address. This didn’t seem possible. On further investigation I found that I had unintentionally turned on my test Apache web server’s directory listing feature (on real web sites I always disable this big security hole). The harvester used the directory listing to find the site’s list of files and then scanned each one, including the AJAX PHP script which contained the protected address. With directory listings disabled, the harvester no longer found the AJAX address. Tricky JavaScript won’t protect you if the web server is misconfigured.

The JavaScript methods all require that the visitor’s web browser have JavaScript enabled. W3schools.com maintains monthly statistics on browser usage and reports that in 2007 about 94% of visitors had JavaScript enabled. For the remaining 6%, these methods will show a blank email address. However, your visitor statistics may be different. At one time, large corporate or government sites mandated disabling JavaScript to reduce the number of viruses sneaking past Internet Explorer’s many bugs. If your site is aimed at these visitors, you may have fewer visitors with JavaScript enabled. If your visitors include those that do not enable JavaScript, these methods have poor usability.

JavaScript methods have good accessibility. Screen readers for the visually impaired work along side web browsers, reading web page text even if it has been added by JavaScript scripts.

CSS text insertion is an effective method, when browsers support it. While most do, Microsoft’s Internet Explorer 7 still does not. Until Microsoft upgrades their browser, CSS text insertion is not widely supported. Even then, the text inserted by CSS cannot be selected for a copy and paste into the visitor’s email program, and it cannot be read by screen readers for the visually impaired. CSS text insertion has poor usability and accessibility.

Recommendation: JavaScript text insertion works pretty well to protect an email address from spambots, but it is awkward to author and maintain. The other articles in this series discuss more methods to protect email addresses, including several effective methods that don’t require JavaScript.

Further reading

The principal article of this series on Effective methods to protect email addresses from spammers lists the other series articles, summarizes their results, and provides a list of web resources for further reading.

Comments

Simple Javascript may not work...

I have been using Javascript to obscure email addresses for years, but recently it seems that harvesters were able to decode my address and I have had tremendous amounts of spam ever since. of course there is no way to know for sure how exactly my email address was retrieved, but it got me thinking.

If screen readers can decode javascript, why not spammers? Seems simple enough.
If (using IE) you view a "protected" page which uses javascript obfuscation, then save the page "as text", the email address will be output in plain text.
I believe one could easily use Visual Basic and some IE Active X control to render pages (javascript, css and all) at high speed.
Using this method, harvesters would be indistinguishable from a real user hitting the site using IE.

So, I am stumped... seems like we need a system that is better than simple javascript obfuscation.

Perhaps prompt the user for a string, then use that to decode the email in the browser.
Or use something like mouse movement (which only exists when a user is present) to test the "human-ness" of the user.

Just ideas...

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

Nadeau software consulting
Nadeau software consulting