Developer notes
Overview · Installation · Configuration · Usage · FAQ
How it plugs into CS-Cart
Section titled “How it plugs into CS-Cart”CS-Cart has an antibot service (Tygh::$app['antibot'], Tygh\Web\Antibot) with replaceable drivers, the rule schema security/antibot_rules (which POST requests are checked under which scenario) and the template common/image_verification.tpl that forms include. Captcha Pro uses all three instead of a parallel mechanism:
init.phpextends the service withTygh\Addons\KvCaptchaPro\Antibot(a subclass of the core class) and its driverDriver(IAntibotDriver,IErrorableAntibotDriver), only while the add-on is enabled, licensed and Google reCAPTCHA has no keys. The driver cannot be replaced by another add-on afterwards.- The subclass reads the form settings of the add-on instead of Image verification: Use for, never writes session flags (every submission is checked, so cached pages stay identical for all guests) and skips signed-in users per the settings.
schemas/security/antibot_rules.post.phpadds rules core does not ship (auth.recover_password,product_reviews.add,products.product_notifications) and makes every rule end the request on failure: rules that “redirect” without a URL get a real target andterminate_processbecomes a denial. Without this, a failed check onauth.loginwithoutredirect_urlstill ran the sign-in controller.- The template override
common/image_verification.tplrenders the widget while Captcha Pro is active and otherwise the reCAPTCHA template or the unchanged core content. - The admin and vendor panel sign-in (not covered by core) is checked in
controllers/backend/auth.pre.php.
The checks
Section titled “The checks”- Allow-list: the visitor IP (
IpList::visitorIp():REMOTE_ADDR; forwarded headers only from loopback, private or configured proxies,X-Forwarded-Forwalked from the right) against the allowed addresses. - Rate limit: fixed window per form and IP (
kv_cp_rate, one atomicINSERT … ON DUPLICATE KEY UPDATE; the IP is stored only as an HMAC). - Honeypot: the hidden field
kv_cp_websitemust be empty. - Ticket:
kv_captcha_pro.ticket(storefront) orauth.kv_cp_ticket(panels) returns a signed ticketbase64url(JSON {v, f, ts, n, d, c}) . "." . HMAC; no session, no database write. The browser finds a nonce so thatSHA-256(ticket ":" nonce)starts withdzero bits (12/15/18, +3 when the visitor used half the attempts). The server checks the signature (key derived from the install secret andcrypt_key), form, storefront, age (minimum time, 30-minute lifetime), the work, and single use (kv_cp_used). - Provider: Turnstile (
challenges.cloudflare.com/turnstile/v0/siteverify,actionmust equal the form,idempotency_key) or hCaptcha (api.hcaptcha.com/siteverify,sitekey). In provider mode the ticket carries the time check and, with the built-in fallback, the work; a provider outage or a widget that cannot load (kv_cp_fallback=1) is accepted only with a solved ticket.
Outcomes are counted per day in kv_cp_stats.
Full page cache (4.21)
Section titled “Full page cache (4.21)”The widget markup and the script settings depend only on the add-on settings. Tickets come from a non-cacheable dispatch; checks write only own tables on POST. No ?:storage_data writes.
Data model
Section titled “Data model”| Table | Content |
|---|---|
kv_cp_forms |
form, company_id, status (A check, L rate limit only, D off), attempts, window_min |
kv_cp_rate |
bucket (HMAC of storefront, form, IP), hits, window_start, expires_at |
kv_cp_used |
SHA-256 of used tickets until they expire |
kv_cp_stats |
day, company_id, form, outcome, hits |
Endpoints and hooks
Section titled “Endpoints and hooks”index.php?dispatch=kv_captcha_pro.ticket&form=<form> and admin.php|vendor.php?dispatch=auth.kv_cp_ticket (JSON). Templates: storefront override common/image_verification.tpl, index:scripts / index:styles (.post); admin auth:login_form (.post), index:styles, addons:tabs_content, addons:manage. Controllers: frontend init.post, kv_captcha_pro; backend auth.pre, auth.post, kv_captcha_pro. Schemas: security/antibot_rules, menu/menu, permissions/admin, gdpr/klaro_config (Turnstile/hCaptcha listed as strictly necessary in the GDPR add-on’s consent dialog). No PHP hooks besides the generated upgrade hook.
To protect a form of your own add-on, include common/image_verification.tpl with your scenario in the form, add a rule in your schemas/security/antibot_rules.post.php and register the scenario with the settings_variants_image_verification_use_for hook: it then appears on the Spam protection page.
License check
Section titled “License check”Tygh\Addons\KvCaptchaPro\License\Client (generated) verifies the license. Gate: Config::isActive(), which decides whether Captcha Pro takes over the antibot service, renders the widget, issues tickets and checks the panel sign-in.
Not in 1.0.0
Section titled “Not in 1.0.0”Google reCAPTCHA as a provider (use the built-in add-on), Friendly Captcha / ALTCHA widgets, per-country rules, IP reputation lists.
File map
Section titled “File map”| Path | Purpose |
|---|---|
app/addons/kv_captcha_pro/addon.xml |
Settings, tables |
init.php, func.php |
Service extension, install secret, ticket responder, settings status |
Tygh/Addons/KvCaptchaPro/Antibot.php, Driver.php |
Antibot service subclass and driver |
Ticket.php, ProviderVerifier.php, RateLimiter.php, IpList.php |
Checks |
Forms.php, Stats.php, Coexist.php, Config.php, Bootstrap.php, Admin.php |
Form settings, statistics, Google reCAPTCHA, settings, view data, admin page |
License/, controllers/backend/kv_captcha_pro_license.php |
License check (generated) |
Upgrade/Synchronizer.php |
Self-healing upgrades (generated) |
controllers/, schemas/ |
Endpoints, admin page, rules, menu, permissions, consent |
var/themes_repository/responsive/templates/addons/kv_captcha_pro/ |
Widget, template override, scripts |
design/backend/templates/addons/kv_captcha_pro/ |
Admin page, settings status, panel sign-in widget |
js/addons/kv_captcha_pro/func.js |
Widget script: SHA-256 proof of work, provider loading, form hold and resend |