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 2 of 4
Sorry to bring up an old thread, but I didn't want to reinvent the wheel if I don't have to.

Would it be possible to have Couch include a <cms:spam_question /> and <cms:input type='spam' /> which would show an anti-spam question and input field for it, respectively? It could just grab from a pre-defined list (the list could be in a file somewhere, so if the developer wanted to add to it, they could). Then you could just do something like:

Code: Select all
<label for="spam">Please answer the question:</label>
<span class="spam-question"><cms:spam_question /></span>
<cms:input type='spam' name='spam' id='spam' />


Also, have it assume it's required. Along the same vein...the captcha tag is no longer working (the image isn't displayed) so could it be removed if something like this is implemented?

Thanks!

EDIT: It may be better (and less work) to simply replace the captcha tag with a recaptcha tag https://www.google.com/recaptcha/intro/index.html

EDIT 2: Another option would be creating a honeypot tag: http://www.midwesternmac.com/blogs/jeff ... -form-spam

P.S. I know a decent amount of php (and what I don't know, I can learn), so if you'd like help implementing this (and can help me work through the Couch code on Github...I haven't looked, so I don't know how well it's commented/documented) I'd be more than happy to do this myself :)
Google's new ReCaptcha is pretty slick and very easy for humans to use. I think a new Couch recaptcha tag would be a worthwhile addition. I've shied away from challenge questions because I'd prefer to tolerate a little spam rather than create hurdles for users. But the new ReCaptcha is very easy. It's even kind of fun!

A honeypot is fairly straightforward to make in raw code, but maybe a tag would simplify it. I'm using a variation of the honeypot that uses 2 hidden input fields, one empty and one with a preset value, making it a little harder for spambots to figure out (maybe).

Depending on what your form is meant for, one of the best unobtrusive pre-processing tricks I've seen is simply to not allow or restrict the number of URLs submitted. Since almost all spam contains links (that's kind of its purpose for being), no urls means no spam. My contact form settings allow no more than one url. So if someone wants to include a link, that's cool. But spambots don't seem to be able to resist the temptation to send multiple links. How you handle this would depend on your expectations for the form.

P.S. A new validator max_urls could provide this functionality.
Code: Select all
validator='max_urls=0'

I'm more of a copy-and-paste coder, but with some more accessible guidance, I might try contributing small improvements, custom tags, and addons, too. :)
How could I implement a honeypot using couch's form (without a couch tag)? Is there a way to run my own validation before couch's validation (or after?).
For a dual-field honeypot in a Couch form, add two additional fields to your form and hide them from humans with a CSS class.
Code: Select all
<p class="hidden">Leave these as-is. It's a trap!
    <cms:input type="text" name="honeypot"/>
    <cms:input type="text" name="honey" value="pot"/>
</p>

Then in your form's k_success processing, check first to see if the honeypot has been disturbed.

Code: Select all
<cms:if k_success >
   <cms:if frm_honeypot || frm_honey != 'pot'>
       <h3>You filled in a field meant to trap spambots. If you're a human, please try again and leave those fields undisturbed.</h3>
       <!-- Optional alert to the webmaster. You can remove this once the form has been fully tested. -->
       <cms:send_mail from=k_email_from to='webmaster@clientsite.com' subject='Honeypot Triggered'>
           The honeypot on this form was triggered.
           <cms:show k_success />
       </cms:send_mail>
    <cms:else/>
       ...Process form...
    </cms:if>
</cms:if>

The form and the alert both have explanations in case a human gets caught. I've read conflicting information about how screen readers process display:none; and also about whether spambots can read these warnings, but providing warnings seems to be an accepted best practice.

There are two theories about naming your honeypot fields that both make sense:
1. Name the field something enticing to spambots - like "website" or "url" - or something they expect to fill in - like "subject" or "email" - in order to encourage spambots to fiddle with it.
2. Use random names to prevent spambots from learning to avoid them.

"Honeypot" is used in the example for clarity, but may not be the best choice. I don't really know.

Anecdotal evidence suggests that a honeypot can be an effective unobtrusive spam prevention technique for low to moderate traffic sites. For more popular sites, you may need more.

I think this also answers your question about pre-processing or post-processing a Couch form, but if not, let me know. Hope this helps.
Like I mentioned above, the best unobtrusive spam protection technique that I've ever used is limiting the number of URLs allowed in a message. This technique won't work for every kind of form but it's excellent for ordinary contact forms. In my experience with low to moderate traffic sites, this technique effectively eliminates contact form spam without requiring anything from legitimate users.

I learned this technique from Tectite's FormMail (http://www.tectite.com), a free open-source form processing script. I have adapted it for Couch. Add this code to the form's if k_success processing. Simply set the form field you want to test and the number of URLs allowed.
Code: Select all
    <cms:if k_success >
       
<!--Too Many URLS-->
<cms:php>
    global $CTX;
       
    //**SET** the form field to be tested.
    $target= "<cms:show frm_message/>";

    $url_patterns = '/((\bhttps{0,1}:\/\/|<\s*a\s+href=["'."'".']{0,1})[-a-z0-9.]+\b)|(^|[^-a-z_.0-9]+)(?<!@)([-a-z0-9]+\.)+(com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx| ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz| ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu| fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it| ja|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly| ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz| na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw| sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz| ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/msi';

    $url_count = preg_match_all($url_patterns, $target, $each_url);
    $CTX->set( 'url_count', $url_count );
</cms:php>
   
        <!--**SET** the # of URLs allowed-->
        <cms:if url_count gt '1'>

<p class="error_msg">Sorry. There are too many URLs in your message.<br>If you need to send us a link, please contact us first.</p>
           
<cms:ignore>
<!--Alert to webmaster. Enable for monitoring, testing, and debugging.-->           
            <cms:send_mail from=k_email_from  to='webmaster@mysite.com' subject="<cms:show k_template_title/> Alert" debug='1' logfile="contact-alert.txt">
The spam prevention on this form was triggered by a submission.

<cms:each k_success ><cms:show item />
</cms:each>
            </cms:send_mail>
</cms:ignore>
         
        <cms:else/>           
           ...Not spam. Process form...
        </cms:if>
    </cms:if>
@tim,

That seems to be a useful technique.
Why don't you encapsulate all that PHP logic into a single Couch tag? Would become very easy to incorporate e.g.
Code: Select all
<cms:if "<cms:urls_exceed '3' in=frm_message />">
    <p class="error_msg">
        ..
    </p>
</cms:if>

Would be nice if you release it here :)
Good idea, @KK. Here you go.

Unzip the too-many-urls folder and place it in your couch/addons folder. Register it in k_functions.php:
Code: Select all
require_once( K_COUCH_DIR.'addons/too-may-urls/too_many_urls.php' );

The tag is used in the k_success routine of a form to limit the number of urls allowed in a field. For example:
Code: Select all
    <cms:if k_success >
        <cms:if "<cms:too_many_urls in='frm_message' max='1' />" >
            <p class="error_msg">Sorry. There are too many URLs in your message. If you need to send us a link, please contact us first.</p>
        <cms:else/>
           ...Not spam. Process form...
        </cms:if>
    </cms:if>

If the "max" parameter is not specified, the default is '1', which I've found to be an effective setting for spam control. For some reason, spammers seem to like sending multiple links. But if your site users wouldn't ever need to send links, go ahead and set the 'max' parameter to 0.

For my own purposes I send every blocked message to the webmaster (me) for monitoring and so that I can forward any legitimate messages on to the site owner.

Attachments

Thanks Tim :)
In real life usage, I discovered an error in the original pattern matching that would create false positives when someone misses a space after a period.Like this. I corrected the error in the snippet above and updated the zip file.
I never thanked y'all for this, but it's been VERY helpful! :)

I was wondering though...is there a way to prevent the honeypot fields being added to k_success and being sent?

Also, @tim, I included your addon in my couch boilerplate: https://github.com/Mako88/thatguy-boilerplate (If you'd rather I didn't, just let me know and I'll remove it).

Thank y'all a bunch!
32 posts Page 2 of 4
cron