Download
We're evolving to serve you better! This current forum has transitioned to read-only mode. For new discussions, support, and engagement, we've moved to GitHub Discussions.

Documentation: Hide an e-mail address from a spam bot

  • #2393
    Avatar photo[anonymous]

    I spent a few hours reading about all kind of ways to hide an email address from a spam bot but there wasn’t a single one that I really liked. Therefor I wrote my own implementation. I’m not completely sure that it works 100% but I hope it’s good enough.

    HTML

    
    
    

    JavaScript

        <script>
         	      
        	function addEmailAddresses(){	 	
    
          document.querySelectorAll('.email').forEach(function(linkElement) {
          
            var domainname = window.atob("[domain name of the email address]");
            var username = window.atob(linkElement.getAttribute("id"));
            var emailaddress = username + "@" + domainname;
            var mailto = window.atob("bWFpbHRv");  // mailto:
            linkElement.innerHTML = emailaddress;
            linkElement.setAttribute("href", mailto + ":" + emailaddress);
          });	  	
    
        }
        		    
        </script>
        
        
    </head>
    
    <body onload="addEmailAddresses()"
    #2394
    Avatar photo[anonymous]

    The Wordfence settings are too tight and I can’t add any HTML-code.

    In words:

    • Add the class email to the a-tag.
    • Add the username part of the email address, encrypted with the JavaScript function <span class=”jscolor”>window.<span class=”jspropertycolor”>btoa</span>()</span>, to the id of the a-tag.
    #2395
    Avatar photo[anonymous]

    Remove all the HTML in the above comment and you know what I mean ;-).

    #2411
    Avatar photo[anonymous]

    Very clever! Thank you.

    Wouldn’t  a human be able to get the email address from the page source?

    #2423
    Avatar photo[anonymous]

    During the loading of the page the e-mail address is not visible, after loading it is!

    And of course a human is always able to read the e-mail address. That’s the whole point! Only spam bots can’t read it.

    I tried to upload the code again but every time I get a message from Wordfence that I use some code that isn’t allowed.

    #2428
    Avatar photo[anonymous]

    Ah okay, thanks, I understand now. That’s why Contact Forms were invented I guess. A well-made form does not display the receiving email address. That way, it not only protects against the spam bots, but even a human cannot read the address. This human could be head of an army of  a thousand spam bots…

    #2430
    Avatar photo[anonymous]
    [anonymous] wrote:

    Ah okay, thanks, I understand now. That’s why Contact Forms were invented I guess. A well-made form does not display the receiving email address. That way, it not only protects against the spam bots, but even a human cannot read the address. This human could be head of an army of a thousand spam bots…

    You’re right ! Contact forms are pretty useful if you want to avoid bots collecting email adresses. But they are known to be exploited by bots too and they could be very annoying. You can use other protections (captchas, honeypots …) to avoid this. But it’s an other topic ^^

    Therefore Verhoeckx your idea is really nice 🙂 But you could do something even more tricky for bots. Here, if your bot can render js, it can collect the mail address. Here is another version a little bit easier to read and without any way to bots to get your address (in my example the address is foo@bar.com) :

    First the HTML part :

    <span class="mail_link" data-user="foo" data-server="bar" data-extension="com">Send me an email</span>

    As you can see it’s not even a link. No spambot will follow something that doesn’t look like a link isn’t it ? Just some attributes and a class to detect your pseudo link 🙂

    Then for the js, I’m not really good for vanilla so I’ll give you jQuery :

    $("span.mail_link").click(function () {
        var email=$(this).data("user")+"@"+$(this).data("server")+"."+$(this).data("extension");
        location.href="mailto:"+email;
    });

    When you click on your pseudo link, you recreate the email address from the data attributes and then you just ask for your browser to open your mailto link 😉 Once again, my vanilla js is a bit rusty but it can be very simply converted into vanilla js code.

    And to get a nice UX touch, a bit of css :

    span.mail_link {
      cursor: pointer;
    }
    

    Just to have the little hand cursor when your mouse comes over the pseudo-link.

    You can even encode your fields if you’re really paranoid. But I think it would be a bit too much…

    #2431
    Avatar photo[anonymous]

    Great thinking, Champi!

    But I think Verhoeckx’s solution is better. Because it is way cleverer and more complicated.

    If I were a spam bot reading your code, I would see  <span class=”st0″>”mail_link”>, which would trigger my attention.

    Then I would see : <span class=””>data-server=</span><span class=”st0″>”bar”</span> , where  “bar” in reality would be “gmail” or similar, further arousing my interest.

    The extension “.com” would remove my doubts.

    Then, the jQuery would read like an open book for an educated spam bot like me 😉

    Just my impression, an amateur designer thinking out loud. 🙂

    #2433
    Avatar photo[anonymous]
    [anonymous] wrote:

    If I were a spam bot reading your code, I would see <span class=”st0″>”mail_link”>, which would trigger my attention.
    Then I would see : <span class=””>data-server=</span><span class=”st0″>”bar”</span> , where “bar” in reality would be “gmail” or similar, further arousing my interest.
    The extension “.com” would remove my doubts.

    Ok maybe if you’re that paranoid you could use more subtile names for your attiributes, removing the classname (you can just select your DOM element from the attribute) AND encode your datas into base64 to completely fuck the bot. And if you’re even more paranoid, randomize the name of you’re attribute (easy to do in php but I’m not sure that you can do that easily on a static website) like facebook does (just look at the name of the classes on a facebook page and reload…)

    But for a bit of experience, bots are not that clever. From now. Indeed we use this technique to obfuscate links to google bots in SEO. And it works like a charm. We replace by <span data-target> and the location.href do the job.

    But once again, the best solution is to use a form with a honeypot (I hate captchas). Prevents 100% of spam from now on every websites I developed.

    #2434
    Avatar photo[anonymous]

    Here is the ultimate improved code (indeed exactly the one we use in our agency to counter google bots and improve seo)

    <span fusb="Zm9vQGJhci5jb20=">Send me an email</span>
    The rest of my webpage here
    <script>
        $("*[fusb]").click(function () {
            location.href="mailto:"+atob($(this).attr("fusb"));
        });
    </script>
    #2442
    Avatar photo[anonymous]

    Hello Champi,

    I do like your solution too! It’s simpler and uses less code.

    But I also think that both our solutions suffer from the same problem: if a spam bot is able to execute the JavaScript it in both cases is able to retrieve the e-mail address. I guess there isn’t a 100% safe solution.

    Somewhere in the coming weeks I have to build a few forms. Can you tell me what honeypots are and how they work? A link to a website is also good.

    Verhoeckx

    #2456
    Avatar photo[anonymous]
    [anonymous] wrote:

    Somewhere in the coming weeks I have to build a few forms. Can you tell me what honeypots are and how they work? A link to a website is also good.

    First I’ll explain what is a honeypot. In a form you have a field which is invisible to the normal humans but visible to bots (and really attractive to complete). If this field is completed, then I don’t send the form. If it’s empty I send the form. You should not just block the send button or do nothing. You should do everything as if the message had been sent but send the message. If you use an “thank you page, you should redirect to this page (without sending) or if you just display a message to confirm that the message has been sent, just display it. The bot will think that the message has been sent but it will not really be sent 😉

    I’m used to do forms in php but I think this ca easily be converted in js.

    So here is an example of form with my honeypot :

    <form method="post">
        <input id="login" name="login" type="checkbox" value="Y" tabindex="-1" autocomplete="false">
        <input type="text" name="name" value="" id="name"  required="">
        <input type="submit" value="Submit">
    </form>

    The honeypot field here is the login one.

    I can just hide it in css for example (display none or visibility hidden or position absolute left -10000).

    Then in php :

    if (isset($_POST['login']) && $_POST['login'] == 'Y') {
        // Honeypot (here it's a redirection)
        $header = "Location: thankyou.html";
    } else {
        // Code used to send the mail
    }
    

    In javascript (once again, jQuery, sorry guys ^^ but it’s so easier !) you can have the same effect like this (I haven’t tested this code, there might be some bugs but I think it’s easy to understand) :

    $("form input[type='submit']").click(function (e) {
        var form = $(this).closest('form');
        var check = $("input[name='login']",form).val();
        if(check=='Y'){ // If honeypot is lit
            e.preventDefault(); // We don't send the form
            // Do something that looks as if the form was sent...
        } 
    });
    

    If someone click on a submit button, I simply check the honey field in this form and if the checkbox is checked, I don’t send the form. That’s easy and it should work as good as the php method.

    The advantage of php in this situation is that the bot can inspect whatever it wants, the only one to know if it should send the form is the server. everything is decided server side. In js, it could maybe detect somehow if the form was sent or not. But I think it’s already a really good protection against spambots.

    #2461
    Avatar photo[anonymous]

    Hello Champi,

    Thanks a lot for your explanation! It’s really clear! When I’m going to build some forms I will definitely implement this!

    One question however: I know that the code you gave is just an example but I think you have to leave out the code value=Y because otherwise the value Y is always send to the server. Instead, I think, you have to check if the value is not null?

    Verhoeckx

    #2468
    Avatar photo[anonymous]
    [anonymous] wrote:

    One question however: I know that the code you gave is just an example but I think you have to leave out the code value=Y because otherwise the value Y is always send to the server. Instead, I think, you have to check if the value is not null?

    Indeed you’re right. I did a little mistake. You can just check if the inout is or is not checked. You ca use a simple input too. just check the length of the value and if it’s not equal to zero, then prevent the form send.

    Now the correct code :

    $("form input[type='submit']").click(function (e) {
        var form = $(this).closest('form');
    if ($("input[name='login']",form).is(':checked')) { // If honeypot is lit
            e.preventDefault(); // We don't send the form
            // Do something that looks as if the form was sent...
        } 
    });
    #2472
    Avatar photo[anonymous]

    Then I understood your code correctly :-)!