Preventing 100% of automated form spam

Franz Rodenacker
3 min readJun 9, 2022

There is a war going on between form spammers and anti-spammers. It seems that as soon as one effective spam prevention method gains traction on the web, spammers write clever code to get around it. Those laboring to prevent spam and those writing spam bots are engaged in a never ending battle to find increasingly sophisticated techniques to achieve their respective goals.

The main spam problem most websites have is not the odd manual spammer, but automated form submissions by bots. Manual spamming is infinitely more expensive than automated spamming and is therefore reasonably rare — at least on less-trafficked websites. Bots sometimes submit a contact form several times a day, and can easily account for over 80% of all form submissions on a site. This is not just a waste of time and incredibly annoying, but also distorts website analytics and other metrics.

I have spent some time testing a variety of anti-spam methods in the wild and found that none of the popular methods work very well. CAPTCHAs and other methods forcing people to prove their humanity are annoying and not user friendly. There are worrying privacy concerns with Google’s reCAPTCHA. Besides, all cookie methods may just be phased out by more privacy-conscious browser versions in the near future. Methods like the honeypot, blocking spammers IP addresses, using session cookies or measuring the visitors time on page are either not reliable enough, technically tricky or have the potential to block real user submissions.

The “Custom Tag Method”

Considering these drawbacks, I decided to develop my own anti-spam method, called the “Custom Tag” method. I have been using this method very successfully for some time now and have not had a single spam submission since implementing it! The “Custom Tag Method” is simple to implement, does not invade anyone’s privacy and does not require people to prove their humanness. I use it with form elements, but it actually works with any html element and in all modern browsers.

The “Custom Tag Method” relies on the fact that spam bots do not execute Javascript. It uses a small script that scans the page for custom tags (in my case I use <f-f></f-f>) and converts such tags to html elements when the page loads. This means that forms do not need to contain any of the classic form elements, like inputs, textareas or selects, only non-standard custom tags. When bots scan the page they don’t find any fields to populate and just move on.

How it works

  1. Add an opening and a closing tag (!) with the name f-f
<f-f></f-f>

2. Add a “el” attribute with the element you want to create, for example

<f-f el=”input”></f-f>
<f-f el=”textarea”></f-f>
<f-f el=”select”></f-f>

3. Add any attributes you want your element to have, for example

<f-f el=”input” type=”text” name=”name” class=”formel”></f-f>
<f-f el=”input” type=”checkbox” name=”mycheckbox” value=”Yes” checked></f-f>
<f-f el=”input” type=”radio” name=”mycheckbox” value=”No” checked></f-f>
<f-f el=”textarea” name=”message” style=”height:40px;width:200px;”></f-f>
<f-f el=”select” name=”mycheckbox2"><option value=”Monday”>Monday</option><option value=”Tuesday”>Tuesday</option></f-f>

4. Add the script below to the page. When the page loads it creates a new element using the “el” attribute in all f-f elements. It then adds all other attributes and all child elements to the new element before removing the f-f element from the DOM.

<script>
document.addEventListener("DOMContentLoaded", function () {
window.customElements.define('f-f', class extends HTMLElement {});
const els = document.getElementsByTagName("f-f");
for (let i=els.length-1;i>=0;i--){
let attrs = els[i].getAttributeNames().reduce((acc, name) => {
return {...acc, [name]: els[i].getAttribute(name)};
}, {});
let el = document.createElement(attrs["el"]);
for (let key in attrs){
if(attrs.hasOwnProperty(key) && key != "el"){
el.setAttribute(`${key}`, `${attrs[key]}`);
}
}
while (els[i].childNodes.length > 0) {
el.appendChild(els[i].childNodes[0]);
}
els[i].parentNode.insertBefore(el, els[i]);
els[i].remove();
}
});
</script>

Check out the Github repo https://github.com/rodenacker/FormSpamPrevention

What spam prevention method do you use? Let me know in the comments!

Readings

https://blog.cloudflare.com/introducing-cryptographic-attestation-of-personhood/
https://blog.cloudflare.com/moving-from-recaptcha-to-hcaptcha/
https://www.fastcompany.com/90369697/googles-new-recaptcha-has-a-dark-side
https://human-id.org/blog/recaptcha-how-much-will-we-give-up/
https://wpmailsmtp.com/best-recaptcha-alternatives/
https://www.bairesdev.com/blog/4-methods-to-fight-against-spam/

--

--

Franz Rodenacker

Product Designer, Frontend Developer and Usability Engineer at Digiata