[edited] Contact form w/spam protection?

Post Reply
gpPixelworks
Posts: 1
Joined: Fri Dec 10, 2021 11:39 am

[edited] Contact form w/spam protection?

Post by gpPixelworks »

Exploring WonderCMS and was curious if there is a simple way to add spam protection to the current Contact plugin.

Perhaps adding in something like hCaptcha?

Edit:

To add captcha one need add just these two lines to the form <div>:

Code: Select all

<div class="h-captcha" data-sitekey="xxxxx"></div>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
I've looked at contact-form.php and tried several way to insert the code, above, but wasn't successful having it added where it would function with the contact form.

Any suggestions on what may work?
User avatar
wiz
Posts: 749
Joined: Sat Oct 30, 2010 12:23 am

Re: [edited] Contact form w/spam protection?

Post by wiz »

1. Where in contact-form.php did you do the changes? Some exact line would help.
It seems starting with line 189 would be the correct lines to put this in.

2. Can you provide a sample website to see how it shows up or anything happening with the form itself?
jetshack
Posts: 10
Joined: Wed May 30, 2012 8:47 pm

Re: [edited] Contact form w/spam protection?

Post by jetshack »

I installed the contact form plugin yesterday.

Today I have over 100 spam emails.

I added the captcha hooks and was able to get it "working" but...

The submit button isn't connected to the captcha. So you can still submit the form without completing the captcha.

And that's why I have 100 spam messages in my inbox.
grimblefritz
Posts: 16
Joined: Tue Apr 25, 2023 1:21 pm

Re: [SOLVED] Contact form w/spam protection?

Post by grimblefritz »

I have this working. I'll try to describe the solution so it's useful for everyone.

First, of course, go to hcaptcha.com and register. This will get you the "sitekey" and "secret" you'll need.

Next, you'll make a couple of edits to your theme.php. I use the Clean theme. If you are using a different on, then you might need to make some adjustments to these instructions.

Find the <link> that loads the theme's style sheet. Below that, add:

Code: Select all

        <?php // include hCaptcha but only for pages named 'contact'
        if ($Wcms->currentPage == 'contact') {
                echo '<script src="https://js.hcaptcha.com/1/api.js?hl=en" async defer></script>';
        } ?>
I only want the captcha on the contact page, hence the "if" block.

Still in the theme.php, toward the bottom, find the "if (!Wcms->loggedIn)" block. After (not inside) that block, add:

Code: Select all

        <?php // include hCaptcha submit test, but only for pages named 'contact'
        if ($Wcms->currentPage == 'contact') { ?>
        <script>
        $("form").submit(function(event) {
            var hcaptchaVal = $('[name=h-captcha-response]').val();
            if (hcaptchaVal === "") {
              event.preventDefault();
              alert("Please complete the hCaptcha");
            }
        });
        </script>
        <?php } ?>
Finally, we need to modify the plugins/contact-form/contact-form.php file.

Inside the <form> locate the <input type=submit> line. Before or after that line, depending on where you want the hcaptcha to appear, add:

Code: Select all

        // add hCaptcha sitekey
        $final_content .= '<div class="h-captcha" data-sitekey="YOUR_SITEKEY"></div>';
You'll need your actual sitekey, of course.

Lastly, find the line "if(isset($_POST..." which should be followed by "$aFout = array()". AFTER the $aFout line, add:

Code: Select all

        // validate the hCaptcha response
        if(isset($_POST['h-captcha-response']) && !empty($_POST['h-captcha-response']))
            {
            $hcaptchaSecret = 'YOUR_SECRET;
            $verifyResponse = file_get_contents('https://hcaptcha.com/siteverify?secret='.$hcaptchaSecret.'&response='.$_POST['h-captcha-response'].'&remoteip='.$_SERVER['REMOTE_ADDR']);
            $responseData = json_decode($verifyResponse);
            if($responseData->success) {
                $hcaptchaOkay = TRUE;
            } else {
                $aFout[] = 'hCaptcha verification failed';
                $hcaptchaOkay = FALSE;
            }
        } else {
            $hcaptchaOkay = TRUE;
        }
As with the sitekey, you need to use your "secret" here.

At this point, hCaptcha should work.

Note that setting $hcaptchaOkay is not necessary and can be omitted. I was using it for something, then dropped it, but didn't change this bit of code.

The key thing is the setting of $aFout[]. If that array is empty, then the contact form is allowed to post. This is how things like missing name or subject get flagged. I've simply co-opted that by setting a message when hcaptcha fails.

I've also used the GET method for verification. The downside of that is 1) it's not guaranteed to be supported, and 2) the recommended POST method is more secure. So, if you want to prevent future headaches, figure out the POST method instead.

As with anything that mods a theme or plugin, to protect your changes from updates you should make copies and work from them.

Hope this helps.
grimblefritz
Posts: 16
Joined: Tue Apr 25, 2023 1:21 pm

Re: [edited] Contact form w/spam protection?

Post by grimblefritz »

BTW, if you want to see how to use POST:

https://www.hcaptcha.com/post/using-hcaptcha-with-php
User avatar
wiz
Posts: 749
Joined: Sat Oct 30, 2010 12:23 am

Re: [edited] Contact form w/spam protection?

Post by wiz »

Hello grimblefritz, thank you for posting this.

We'll be using parts of this with the next update, we just have to figure out a way to use the key via the config and make the config persistent with updates. Right now, the config is reset when we update the plugin. The easiest way will probably be using a seperate database for this (or using the existing one).

As a thank you for your contribution, could you please send your first/last name and website so we can add you to our list of contributors? https://wondercms.com/contributors
grimblefritz
Posts: 16
Joined: Tue Apr 25, 2023 1:21 pm

Re: [edited] Contact form w/spam protection?

Post by grimblefritz »

Cool! I'm glad I could give a little back.

When you do implement it, you should probably use the POST method since GET is deprecated and liable to be dropped at any time.

I don't keep a website for myself, but it's Scott Smith aka grimblefritz.

Thanks!
Post Reply