Proof of work
Браузер молча считает вычислительную задачу. Человеку — доли секунды в фоне, массовой рассылке форм — заметная стоимость на каждой отправке. Цена одинакова с любого адреса, поэтому смена IP не помогает.
Антибот-проверка без внешних сервисов. Ни reCAPTCHA, ни Turnstile, ни чужих ключей — ни один запрос не уходит на сторону. Человек обычно вообще ничего не вводит.
Браузер молча считает вычислительную задачу. Человеку — доли секунды в фоне, массовой рассылке форм — заметная стоимость на каждой отправке. Цена одинакова с любого адреса, поэтому смена IP не помогает.
Поле-ловушка, признаки живого ввода и время заполнения. Время считает сервер по метке выдачи задачи — на него нельзя повлиять с клиента.
Код рисуется векторными штрихами, а не текстом, поэтому ответ нельзя вытащить из разметки. Всплывает только при подозрении.
Кнопка показывает второй режим — так проверка выглядит, когда отправка кажется подозрительной.
Это не картинка и не запись — рабочий виджет, ровно тот же, что встаёт на форму подключённого сайта. Он уже проверил вас, пока вы читали эту строку.
Строки выбраны по тому, что решает при выборе, а не по тому, где Kontur выигрывает. Последняя строка — там, где он проигрывает, и её стоит прочитать раньше остальных.
| Kontur | reCAPTCHA | Turnstile | |
|---|---|---|---|
| Кто видит посетителя | Только ваш сервер и mallaev-dev.ru | Google — и связывает визит с аккаунтом | Cloudflare |
| Что делает человек | Обычно ничего: задача решается в фоне | Обычно ничего, иногда — светофоры | Обычно ничего |
| Если картинку не видно | Задача вместо неё, по одному вычислению | Аудио — и оно распознаётся ботом | Картинки нет вовсе |
| Согласие на обработку | Не нужно: данные не уходят третьим лицам | Нужно упомянуть в политике | Нужно упомянуть в политике |
| Кто чинит, если сломалось | Я, и вы знаете, кому писать | Никто персонально | Никто персонально |
| Устоит против выделенной атаки | Нет — задача решается на видеокарте | Тоже нет, но моделей у них больше | Тоже нет |
Kontur пока в начале пути, и каждое подключение я разбираю лично: смотрю, как проверка ведёт себя на конкретной форме, какие признаки поведения там вообще собираются и где она ошибается на живых людях. На чужой форме всё это выглядит иначе, чем на моей, а вслепую такие вещи не настраиваются. Поэтому ключи сейчас завожу я, и Kontur идёт вместе с сайтом, который я делаю. Когда наберётся достаточно разных форм, чтобы настройки перестали быть ручными, выдача откроется сама.
Заказываете сайт — или уже заказали — тогда шаг пропущен.
Регистрируетесь здесь — учётная запись нужна, чтобы было куда положить ключи.
Я настраиваю проверку — под вашу форму и завожу подключение на вас. Ключи появляются в профиле.
Вписываете домены и тег — дальше всё в ваших руках — секрет и домены меняете сами.
Выданное подключение лежит в разделе Kontur вашего профиля. Что там есть:
knt_site_…Публичный. Ставится в разметку страницы, его видно всем — так же устроены reCAPTCHA и Turnstile.
knt_secret_…Только для вашего сервера. В профиле открывается по вводу текущего пароля. У нас он не хранится в открытом виде: в базе лежат хеш для поиска и шифртекст, ключ от которого не покидает Yandex KMS. Показать его повторно можно, а достать из дампа базы — нет.
обязательноПока список пуст, проверка отклоняет все запросы. Впишите домен сайта, где стоит форма, иначе свежий ключ будет выглядеть сломанным.
Перевыпуск секрета — там же. Прежний перестаёт работать сразу же, поэтому делать это стоит только когда есть куда вписать новый.
Скрипт сам находит блоки с классом kontur, решает задачу в фоне и вставляет в форму скрытое поле kontur-response. Вместо knt_site_… подставьте ключ сайта из профиля.
<script src="https://mallaev-dev.ru/kontur.js" async defer></script> <form method="post" action="/submit"> <input name="email" type="email" required> <div class="kontur" data-sitekey="knt_site_ваш_ключ"></div> <button>Отправить</button> </form>
Секрет никогда не должен попадать в браузер. У адреса проверки намеренно нет заголовков CORS: вызвать его со страницы не получится, и это сразу подскажет, что что-то не так. Сам секрет — из профиля, по подтверждению пароля; если потеряли, там же перевыпускается.
const res = await fetch('https://mallaev-dev.ru/api/kontur/v1/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.KONTUR_SECRET,
response: formData.get('kontur-response'),
}),
});
const { success } = await res.json();
if (!success) return new Response('Проверка не пройдена', { status: 400 });{ "success": true, "hostname": "example.com", "challenge_ts": "2026-08-25T12:00:00Z" }
{ "success": false, "error-codes": ["invalid-response"] }missing-input-secretВ запросе нет поля secretinvalid-input-secretСекрет не найден или сайт выключенmissing-input-responseВ запросе нет поля responseinvalid-responseОтвет повреждён, просрочен или не проходит проверкуchallenge-requiredНужна картинка: показать её человеку и повторить отправкуКлюч сайта публичен по определению — он лежит в разметке, его видно всем. От чужого использования его защищает список разрешённых доменов, и защищает лишь в браузере: заголовок с адресом страницы браузер проставляет сам и не даёт его подделать, а запрос не из браузера может прислать любой. Так же устроены reCAPTCHA и Turnstile — настоящий барьер даёт не привязка к домену, а вычислительная задача: она стоит одинаково при любом заголовке.
Поведенческие признаки подделываются целенаправленным ботом. Они отсекают дешёвую автоматизацию, не более.
Объёмный DDoS — не эта задача. Его гасит инфраструктура хостинга. Kontur занимается злоупотреблениями, которые стоят денег: рассылкой форм, перебором паролей, сливом бюджета на запросы к языковым моделям.
Внешний сервис в схеме всё-таки есть — Yandex KMS, но не на пути проверки. Им зашифрован ваш секрет, чтобы его можно было показать вам второй раз, не храня открытым. Обращение к KMS происходит при выпуске, перевыпуске и показе секрета — то есть считанные разы. Проверка отправки формы ищет сайт по хешу и в KMS не заходит никогда, поэтому недоступность облака её не ломает. На посетителей вашего сайта это не влияет вовсе: их браузер по-прежнему ходит только сюда.
Пока каждое подключение настраивается вручную, Kontur ставится на сайт, который я делаю. Расскажите о задаче — если работа уже идёт, подключение заведу, и оно появится в вашем профиле.