Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
32 posts Page 1 of 4
Just a quick enquiry. I recently finished a site for a client that has a simple blog using Couch.

It is starting to receive quite a lot of spam. The comment form has the captcha and comments have to be approved before they are published.

Is there anything else that can be done? I had thought that the captcha would stop spam. All the spam comments are getting through with the captcha filled in correctly it seems.

The sad reality is that every captcha out there (be it securimage or Google's reCaptcha) has ceased to be effective. Spammers now have bots that can break every single of them.

Our forum also was hit by a spate of spam recently and we had to manually clear literally hundreds of spams on a daily basis. None of the captcha that ships with the forum software had any effect whatsoever.

We experimented with several different ways and finally what proved to be the most effective method of thwarting bots was the 'Answer this question' method.
Our spam level fell from several hundreds a day to a drastic one or two in several days!

Fighting spambots:
All forms created by Couch (the comment submission form included) can easily use this kind of question challenge instead of a captcha. Here is the code to create one within a form
Code: Select all
<label class="required" for="human">Are you human? Is sky blue or green? (4 characters required) <em>* <cms:if k_error_human>Please answer the question</cms:if></em></label>
<cms:input type="text" required='1' validator='regex=/^blue$/i' class="input-text required-entry" id="human" name="human"/>

The question above is: Are you human? Is sky blue or green? (4 characters required)
To check the answer, we use
required='1' validator='regex=/^blue$/i'

Of course, with a little more effort you can have an array of questions (can even use repeatable regions or cloned pages for storing the questions) and then display them randomly.
For our purpose we have found a fixed question good enough to fight off bots.

Fighting human spammers:
The above method will keep bots away but, understandably, nothing can prevent actual human spammers from successfully submitting forms.
To keep human spammers at bay, we deployed a second line of defense -

This wonderful site maintains a list of spammers active around the Internet and provides a free service using which we can submit a user's name, email & IP address and the service will reply back if the user exists in their spammer's list. Brilliant.

I have created an utility script for Couch users that can be used with all forms (including comments) to very easily check with the status of the user submitting a form.

This is how we use it:
IMP: This script requires PHP5 and at least Couchv1.3RC1 (currently downloadable from viewtopic.php?f=5&t=7014).

1. Download the attached below and unzip it to extract the stopforumspam.php contained within.
2. Place stopforumspam.php within the 'addons' folder of your couch installation folder.
3. Edit kfunctions.php present in your main site (if this file is not present please see ... codes.html where its use is discussed and a sample file is available for download and use) and add the following highlighted line of code somewhere at the top
if ( !defined('K_COUCH_DIR') ) die(); // cannot be loaded directly

require_once( K_COUCH_DIR.'addons/stopforumspam.php' );

This will now make stopforumspam.php a part of Couch's code.

If you are wondering what this stopforumspam.php does - it actually defines a custom tag named stop_spam for us. The following step shows how to use this tag.
4. In the comment form, suppose following is the portion of code where we check if the form has been successfully submitted and then take appropriate action (for comments, we use <cms:process_comment /> to store the comment in database) -
Code: Select all
<cms:form method="post" class="k_form">

   <cms:if k_success >
      <cms:process_comment />

immediately before taking the action on successful form submission (using <cms:process_comment /> in above example), insert the <cms:stop_spam /> tag -
Code: Select all
<cms:form method="post" class="k_form">

   <cms:if k_success >
      <cms:stop_spam />
      <cms:process_comment />

And that is it.
The tag will contact and inquire about the status of the user making the submission. If the result flags the user as a spammer - the process is terminated with a message.

For testing purpose, try using the tag providing it with all the parameters manually this way
Code: Select all
<cms:if k_success >
      <cms:stop_spam 'Zac21' '' '' />
      <cms:process_comment />

In the code above we have manually set the username, email and IP address of a known spammer. Try submitting a comment to see what happens.

If you wish to receive an email whenever this tag stops a spammer, please find and edit the following lines in stopforumspam.php
/* Send out an email if someone is rejected? */
var $send_email = FALSE; // make it TRUE if you wish to receive an email if a spammer is stopped
var $email_address = ''; // set this to the account receiving the email

Hope these steps help. Do let me know if you happen to require any help.

UPDATE: With Couch v1.4, the DataBound Forms addon ships with a native tag cms:check_spam that does same job as cms:stop_spam tag mentioned in the discussion above.
For details, please see the 'Handling human spam' section of the addon's documentation at ... forms.html


Thank you KK, this is very helpful.

"Check if user is a spammer, but only if we successfully got the SFS data"
Does this mean that if the website is down for whatever reason, the form will still be able to submit successfully? Additionally, from reviewing the code it appears as though to use this on a non-comments form, such as a contact form, the 'k_author' and 'k_email' input names need to be used. I would appreciate it if you could confirm these conclusions.
Does this mean that if the website is down for whatever reason, the form will still be able to submit successfully?

If the site is down, the attempt to connect will time-out and the submission will go through i.e. succeed regardless of whether it is a spam or not.

it appears as though to use this on a non-comments form, such as a contact form, the 'k_author' and 'k_email' input names need to be used

Not necessary. The stop_spam tag takes optional parameters e.g.
<cms:stop_spam username email ip_address />
so for non-comments form whatever variables hold the username and email can be explicitly passed. The IP address may be skipped because the tag will automatically get it from $_SERVER variables.

Hope this answers your questions.
Wow thanks KK for the very detailed reply.

I will certainly give this a go.
markyards wrote: Wow thanks KK for the very detailed reply.
I will certainly give this a go.

Hi markyards,

Once you've given this a go, it would be great if you could let us know how you are faring with this method and whether you are experiencing less spam. I haven't implemented a comment section yet, but KK's concept sketched above sounds very promising, so it would be very interesting to hear about your recent experiences.

Thanks for any feedback! :)

Is there anything incorrect with adding logging in this fashion:
Code: Select all
$FUNCS->log( $IP.' - '.$username.' - '.$email, 'couch/snippets/rejected.log' );

// Let's kill the posting process with a nice little message
I think it should be perfectly OK to log rejected attempts this way.
Maybe we can find a way to intigrate the following into Couch to confuscate the email and only display it on render...


define( 'K_EMAIL_TO', "<script type='text/javascript'>document.write(theEmailReconstructed);</script>" ); // Email address that will be used in contact forms.
define( 'K_EMAIL_FROM', "<script type='text/javascript'>document.write(theEmailReconstructed);</script>" ); // Will be used as the sender of messages delivered by contact forms to the address above.




<cms:editable name='business_email' label='Business Email' type='text' group='adminInfo'></cms:editable>




<script type="text/javascript">
var theEmail="<cms:php> echo '<cms:get_custom_field 'business_email' masterpage='globals.php' />'; </cms:php>";
var emailE1 = theEmail.split("@")[0];
var emailE2 = theEmail.split("@")[1];
var theEmailReconstructed=(emailE1 + '@' + emailE2);
var theEmailReconstructedwithMailTO = '<a href="mailto:' + theEmailReconstructed + '">' + theEmailReconstructed + '</a>';
var theEmailReconstructedwithMailTOIcon = '<a href="mailto:' + theEmailReconstructed + '">' + '<i class="fa fa-envelope-o fa-inverse fa-2x"></i>' + '</a>';

@developernator, we can use the cms:cloak_email tag for obfuscating email through JS - ... email.html.

Please try it out and let us know your thoughts.
32 posts Page 1 of 4