My projects

Commentail 1.3.0: guest protection and external CAPTCHA

Commentail 1.3.0 adds Google reCAPTCHA and Yandex SmartCaptcha, guest attempt limits, and checks for repeated text and multiple links. Here is how they work and what changes when upgrading.

In brief

  • Google reCAPTCHA v2 and Yandex SmartCaptcha are optional; arithmetic CAPTCHA remains the default.
  • Flagged guest comments and edits go to moderation with private explanations.
  • Forms in separate tabs remain independent, and CAPTCHA errors preserve editable drafts.
The blue Commentail bird on a comment bubble, with version number 1.3.0.
Commentail 1.3.0 — comments for Wagtail websites.

I released Commentail 1.3.0. This release focuses on guest comments: ready-to-use external CAPTCHA adapters, additional form and content checks, and separate submission attempt limits. It also fixes form behaviour across browser tabs and when verification fails.

If you are new to the library, the project page gives an overview. This article covers the changes in this release.

Google reCAPTCHA and Yandex SmartCaptcha

Python settings can now select a ready-to-use Google reCAPTCHA v2 checkbox adapter or the standard Yandex SmartCaptcha widget. Custom CAPTCHA backends retain their existing interface. Without additional configuration, the local arithmetic challenge remains in place; no external service is enabled automatically.

Here is the Google configuration. If your project already has a COMMENTAIL dictionary, merge these options into it.

python
import os

COMMENTAIL = {
    "default": {
        "CAPTCHA_BACKEND": "commentail.captcha_providers.GoogleRecaptcha",
        "CAPTCHA_OPTIONS": {
            "site_key": os.environ["CAPTCHA_SITE_KEY"],
            "secret_key": os.environ["CAPTCHA_SECRET_KEY"],
            "timeout": 3,
        },
    },
}

For Yandex, use commentail.captcha_providers.YandexSmartCaptcha. Create matching keys with the provider and register the actual site domains; keep the secret key on the server. A hostname override replaces CAPTCHA_OPTIONS as a whole, so both keys must be included.

External widgets require JavaScript, including with ordinary HTML form submission. If the selected provider is unavailable, verification is neither skipped nor switched to arithmetic. The text remains editable, and a failed check can be retried. Before connecting a service, review the site privacy disclosures and allowed CSP sources. See the provider guide for details.

The server verifies provider responses through fixed HTTPS endpoints, bounds token and response sizes, and refuses redirects. Hostname checks prevent accepting a response for another site; the timeout is configurable from one to ten seconds, with a three-second default.

Form checks and attempt limits

The guest form now includes a hidden honeypot field, excluded from keyboard navigation and the accessibility tree. Filling it adds a moderation signal. Another signal is submission less than two seconds after form creation. The server owns this timestamp, and recovery preserves the age of a valid draft.

A fast submission does not impose a countdown or reject the comment by itself. Moderators see the reason in the private detail view and can approve the message.

Guest attempts now have limits separate from accepted comments: by default, 10 attempts per session per minute, 30 per IP per minute and 300 per IP per hour, within each site. Failed checks consume this budget too. It is checked before external CAPTCHA verification or mail creation. Adjust the thresholds to actual traffic when many readers share an IP address.

In adaptive mode, a guest with remembered email verification usually skips CAPTCHA; enabled request-header signals can require it again. Setting GUEST_CAPTCHA_MODE to always checks every guest submission. These guest checks do not apply to registered authors.

Rate-ledger cleanup was also corrected: when a site uses an interval longer than one hour, the background pass retains events for the full required period so protection does not reset early.

Repeated text and multiple links

Two new signals examine guest message content. By default, repeated text of at least 80 normalized characters accepted within the previous hour on the same site goes to moderation. Comparison spans discussions and guest email addresses within that site. Letter case, extra whitespace and invisible formatting characters do not conceal a repeat; the original comment text stays unchanged.

The second check flags three or more explicit HTTP(S) or www links. Repeated occurrences of one link count separately; bare domains and email addresses are not matched. The check works even when clickable links are disabled. Short common replies and one or two links do not reach the default thresholds.

Both checks also cover guest author revisions. If an edit is flagged, the published text stays unchanged until a moderator decides. Reasons appear in the private revision detail view. Signals do not automatically delete text; explicit rejection rules still take precedence under the Apply rules policy.

Links are neither sent to reputation services nor fetched by the server. Duplicate detection stores a keyed text fingerprint rather than another copy of the comment. History starts with new accepted guest submissions and proposed revisions: upgrading does not scan old comments.

Configuring the new checks

Thresholds belong in COMMENTAIL and can differ by site. The main options are:

Option Default Purpose
GUEST_CAPTCHA_MODE adaptive When guests must complete CAPTCHA
GUEST_FORM_MIN_SECONDS 2 Fast-submission threshold in seconds
GUEST_DUPLICATE_WINDOW_SECONDS 3600 Duplicate comparison window in seconds
GUEST_DUPLICATE_MIN_LENGTH 80 Minimum normalized text length
GUEST_LINK_REVIEW_THRESHOLD 3 Explicit link count that triggers review

Setting GUEST_FORM_MIN_SECONDS to zero disables timing. Zero GUEST_DUPLICATE_WINDOW_SECONDS or GUEST_LINK_REVIEW_THRESHOLD disables the corresponding content check. Other quotas and email verification remain active. The Wiki lists all settings and limits.

Tabs, long drafts and CAPTCHA errors

Opening or refreshing CAPTCHA in another tab no longer invalidates the current form’s check: bundled forms issue independent challenges. Recovery and navigation preserve the age of a valid draft.

For the bundled Google and Yandex adapters, the local verification binding now lasts as long as the form: one hour by default. A reader can write a long comment before completing a fresh check. This does not extend the provider token: its expiry and single use are checked separately. There are no background renewal requests.

External widgets no longer show a routine task-refresh button; retry becomes available after an error. Arithmetic challenges retain refresh. With an incomplete external check, the enhanced JavaScript form keeps the draft and avoids submitting it prematurely.

Upgrading from 1.2.0

Back up the database, settings, templates, media, SECRET_KEY and exact dependency versions. Rehearse the upgrade on a restored test database with local mail first.

bash
python -m pip install --upgrade commentail==1.3.0
python manage.py migrate
python manage.py check
python manage.py collectstatic --noinput

Migrations 0016 and 0017 add proof state, server-owned form age and private signal lists for comments and revisions. Existing content and queued mail are retained; no dependency changes are required. After collecting static assets, refresh cached resources and restart application and background processes through your project’s normal procedure.

If you override form or CAPTCHA templates, compare them with the new versions. Preserve CSRF, submission keys, challenge fields and the new draft-age and provider hooks. Older forms without the honeypot still work, but cannot supply its signal.

On your own templates, verify guest submission, email confirmation, replies and edits, multiple tabs, and text recovery after errors. Existing mail backends and task queues retain their contracts; keep one background processing schedule.

These checks give moderators additional reasons to review a message and limit attempt frequency. Their effect on real-world spam has not been measured. See the release notes for the complete upgrade procedure and the guest protection guide for detailed behaviour.

Was this article useful?

Comments 0

Name: up to 40 characters.

After submitting, we will email you a link to confirm your email address.

Maximum 5000 characters.

No published comments yet.