Почему мы классифицируем движение руки, а не картинки со светофорами — и как встроить это в форму двумя строками
Картиночные капчи в 2026-м решаются моделями компьютерного зрения за миллисекунды, а каждый ваш клик по «выберите автобусы» бесплатно размечает чужой датасет. Плюс две свежие проблемы: Google в начале 2025 срезал бесплатный лимит reCAPTCHA с 1 000 000 до 10 000 проверок в месяц, а с апреля 2026 ужесточил модель ответственности за данные по GDPR. Из России reCAPTCHA к тому же нестабильна.
В сети существует общая проблема — как доказать, что ты человек, не сдавая паспорт, лицо и номер телефона. Предлагаемое решение: drop‑in капча, которую посетитель не кликает, а рисует. Ниже — архитектура, ML‑часть, приватность и код интеграции. Проект открытый. Визуальное описание процесса ниже
Идея: классифицировать моторику, а не форму
Пользователь рисует произвольный жест ~10 секунд. Мы смотрим не на то, ЧТО нарисовано, а на то, КАК: разброс скорости, паузы, микрокоррекции, ритм, остановки движения руки. Боты двигаются слишком гладко; человек нерегулярен — и эта нерегулярность и есть доказательство. Это та часть, которую боту пока дорого подделать убедительно.
Архитектура: почему iframe с нашего origin
Главная инженерная тонкость встраивания на чужой сайт — cross‑origin. Если бы виджет стучался на наш API напрямую со страницы клиента, ловил бы CORS/Origin‑локи и антибот‑фильтры.
Решение следующее: виджет — это <iframe>, который грузится с нашего домена, а не со страницы клиента. Внутри рамки все запросы идут к нашему же серверу, поэтому никаких cross‑origin проблем нет.
Чтобы понять, чей это сайт, у каждого клиента два ключа (как у reCAPTCHA):
-
публичный (
pk_live_…) — вставляется в HTML, привязан к списку разрешённых доменов клиента. С чужого домена он бесполезен. -
секретный (
sk_live_…) — только на сервере клиента; им подтверждается токен.
Свой домен виджет узнаёт от родительской страницы и перепроверяет на сервере по списку разрешённых — подделать нельзя.
ML: локальный GBM + LLM только для серой зоны
-
Из жеста считаются 8 признаков (velocity variance, pause entropy, rhythm irregularity, correction count и так далее).
-
Локальная градиентно‑бустинговая модель решает уверенные случаи за миллисекунды.
-
Языковая модель подключается только в серой зоне — где GBM не уверен.
-
Fail‑closed: если классификатор недоступен, endpoint отвечает 503, а не «человек: да». Лучше отказать, чем пропустить бота при сбое.
Приватность
Координаты жеста не покидают браузер — на сервер уходит только производная статистика. Никаких картиночных наборов, трекинг‑кук и хранимых биометрических шаблонов. Токен не несёт идентичности. Для GDPR это означает отсутствие передачи данных Google и, для самой проверки, отсутствие требования cookie‑баннера.
Интеграция: две строки + одна серверная проверка
Клиент (в форму, которую защищаем):
<script src="https://homosapience.org/embed/v2/aptogon.js"></script><div data-aptogon-captcha data-aptogon-key="pk_live_..."></div>
<div data-aptogon-captcha data-aptogon-key="pk_live_..."></div>
На успехе загрузчик добавляет в форму скрытое поле aptogon-response. Сервер клиента проверяет токен, как у reCAPTCHA:
curl -s https://homosapience.org/api/captcha/siteverify \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{"token": "<aptogon-response из формы>"}'# → {"success": true, "human": true, "band": "...", "hostname": "https://ваш-сайт"}
-H "Authorization: Bearer sk_live_..." \-H "Content-Type: application/json" \-d '{"token": "<aptogon-response из формы>"}'# → {"success": true, "human": true, "band": "...", "hostname": "https://ваш-сайт"}
Токен одноразовый (повтор — 409), живёт 120 секунд. Секретный ключ — только на сервере.
Честные ограничения
Предлагаемое решение повышает планку, а не делает систему непробиваемой. Мотивированный противник со временем сможет имитировать динамику — как и для любого программного proof‑of‑human. Виджет сам по себе не останавливает распределённые флуды через резидентные прокси. И у «рисования» есть свои ограничения по доступности — встроена толерантность к моторным нарушениям, но это область, где можно проводить исследования и накапливать обратную связь для коррекции алгоритма.
RU‑контекст
В российском сегменте интернета наиболее популярна — Yandex SmartCaptcha (локализация данных, привязка к Yandex Cloud). Наша ниша — те, кому нужна приватность и self‑serve, а reCAPTCHA не подходит по доступности/GDPR.
Итог
Открытый код (AGPL-3.0), бесплатный тариф 1000 проверок/мес. (на стадии тестирования возможно больше). Живое демо: https://homosapience.org/embed/captcha‑demo.html. Документация: https://homosapience.org/developers. Исходники и примеры интеграции (HTML/React/ Node/Python/PHP): https://github.com/tulubyev/aptogon‑captcha.
Буду рад разбору в комментариях — особенно кейсам, где классификатор ошибается, и мнению, действительно ли «нарисовать» ощущается лучше невидимой проверки.
ссылка на оригинал статьи https://habr.com/ru/articles/1072718/