Spam bots have been always been an issue on the internet and they're not unique to Infusionsoft forms. Over the past few months, I have noticed that a seemingly large number of people posting in a Facebook group called “Infusionsoft Open User Group (unofficial)“ have been complaining of a high number of spam submissions through their Infusionsoft app forms. I’ve seen some CAPTCHA solutions posted to the group from various people, but none of them have correctly tackled the problem. I’m going to tell you why these solutions fail, and how you can properly utilize Google reCAPTCHA on your Infusionsoft forms.
First, before I can show you how to implement Google’s reCAPTCHA, I want to take a moment to explain how it works. If you’ve ever been on the internet, you’ve probably come across one of these. This is Google’s most common reCAPTCHA system in use today. It makes it easier compared to the previous garbled letter versions. If Google isn’t sure if you’re a bot or not, they'll bring up a prompt asking you to do certain tasks such as select all the images of cats or select all the squares where a street sign appears. Google actually uses reCAPTCHA as a way to have real humans identify signs, cars, addresses, and more in photos for use in Google Street View and, what I'm assuming as of lately, their self-driving car program, Waymo. By doing this, they can also verify if you’re a human or not by throwing in some data that they already know the answer to. While Google has their own algorithms to determine this, what I wanted to talk about is the actual process of submitting a valid reCAPTCHA.
When you add reCAPTCHA to your form, you have two components that must be implemented: a client-side validation system, and a server-side validation system. These two systems work together to communicate with Google and determine if you pass or not. You may be asking, “Why do I need server-side verification? Why isn’t front-end validation enough?”. The answer is because front-end validation can never be trusted. Let me explain why.
Client-side validation: why you can’t trust the browser
g-recaptcha-response and sets the value to the token. Then you’d typically have a script that, upon submission of the form, verifies that a value was set in that field. If I try to submit the form and it’s not there, I prevent the form from submitting. Easy, right?
The problem is that I can easily do one of two things. First, I could open the console and set the
g-recaptcha-response field to
true or any value I want and then try to re-submit the form, which will now satisfy the variable check function I set up to just make sure it contains a value. Now I’ve bypassed the reCAPTCHA even if I failed. The second thing I could do is run a line of code that would force submit the form, bypassing the submission check all together. So, what would prevent me from doing this? Couldn't I just verify with Google that the token is correct? Yes, we can. This is where server-side verification comes in.
Server-side validation: holding the browser accountable
Once you submit your form and CAPTCHA, we need to talk to Google again and make sure that it’s valid. When you triggered the CAPTCHA, Google took your IP address and stored it along with a one time use token, and returned it back to the browser in the form of the
g-recaptcha-response token. So once we start our server-side validation, we talk to Google again and submit your IP address and your token, and get a response back from Google stating if it’s a) valid, b) matches the same IP address, and c) has not yet been used. If all these things check out, Google gives us the okay and we can proceed to sending the data off to where it needs to go.
If Google says something is wrong, they’ll tell us exactly was wrong and give us an error code. Then we can typically pass this back to the browser and display an error code that the user can understand, such as the CAPTCHA was not passed, or there was a problem with the data submitted. Then the user can try again. This however keeps bots from forcing the form to submit even without passing the CAPTCHA, as I demonstrate above, using the same method as before.
So to recap:
- You click to checkbox to verify you’re not a bot.
- Google grabs your IP address, verifies you’re not a bot, generates a one-time use token, and saves both the token and IP in their system.
- Google sets a hidden field on your form with the token.
- When you submit your form, the server talks to Google again and send your IP and the token they gave you to have Google verify they still match and have not been used yet.
- If your token and IP match, Google gives us the green light. Otherwise, we go back to the form and show an error.
If anywhere through this process Google thinks you’re a bot, you’re going to be stopped from submitting the form. (But keep in mind, while Google stops most bots, they can’t stop all of them, and they can’t stop actual people from submitting crap data.)
How to protect your Infusionsoft forms
So, to finally talk about what you came here for: how to protect your own forms. Well, I think I’ve come up with a nice and easy solution. You saw it working in the GIFs in the sections above, and all it takes is as adding a single line of code to your form. Yes, just one line of code.
Lucky for you, I’m providing this free of charge. I’m hoping that this will help and will save you and your business time and money from having to filter through junk data in your Infusionsoft app. The project's source code can be found here on my Github and is free for you to use as you wish. However, I know that not everybody wants to host their own server, so I’m also allowing you to use my own hosted version of the app. (If you’d like to try it out for yourself, feel free to use the demo I provided here.) Keep reading for more info on how to link to my free script.
How to protect your forms for FREE!
First off, I want to mention this since I’m sure it will come up at some point. I am not looking to harvest any of your data. All data is between you and your users. The information that my proxy receives is simply passed on to your app. Since the source code is posted publicly, you can also verify this for yourself if you wish. I work at Infusionsoft, helping small businesses every day. I made this because I saw an opportunity to solve a problem. If you have any concerns, please feel free to reach out to me personally. I’d be happy to talk. :)
⚠️ Disclaimer: This script is not an official product of Infusionsoft. It is not supported by nor officially affiliated with Infusionsoft. Just a little side project of mine! 😎 Without sounding too legal, please keep in mind the usual things... software is to be used as-is, and may be discontinued at any time, blah blah blah. Just don't come after me if it goes away or something goes wrong please. I'll be happy to try to help, but I cannot guarantee anything.
Okay, with all of that out of the way, here’s how you can protect your form. Here’s the one script you'll need:
Simply insert this script after your closing
</form> tag, replace
YOUR_APP_ID_HERE with your Infusionsoft app ID, and remove the
action="XXXXXXXXXXXXXXX" from your form (so bots can't see the real path to your form). Here's where you'll find your app ID:
⚠️ Please ensure that your form has
class="infusion-form"set on the opening
<form>tag. This is how the script will identify your form. By default, the form HTML provided by your app includes this, but without this set, the script will not work.
Lastly, make sure you disable the "Bot Detection" on your form. If you don't your users may get a double reCAPTCHA.
Options for this script:
Required. You'll need to set you app ID here. You can find it when you login to your app.
data-validate="<true or false>"
Optional. Add form validation so you can't submit empty fields. If you already have your own validation set up, you may want to disable this so they don't interfere.
Optional. If you're hosting this all on your own server, you'll want to put your public key here, otherwise it will default to my key and will not work.
data-inlinestyles="<true or false>"
Optional. Set to true if you want form errors to have inline styles. Set to false if you plan to add your own CSS. We'll still add classes to the errors.
That’s it! Wasn't that easy?
Now when you load your page with the form, you should see the reCAPTCHA banner at the bottom right of your window, and when you submit your form, you might get a CAPTCHA popup (or you might not, if Google doesn't suspect you're a bot). You also should set up some front-end form validation that makes sure all fields are filled out. If you don't have your own, I recommend you use the validation that my script provides. This will prevent your users from seeing your app page with red errors listed at the top of the page. Plus it keeps users on your own page until they submit valid data!
Have questions? Concerns? Not working for you? Please feel free to reach out to me!