הגנה מבוטים ב-2026 — למה reCAPTCHA כבר לא מספיק
AI agents עוברים CAPTCHA בלי בעיה. סקירת הגנה מבוטים מודרנית: Vercel BotID, Cloudflare Turnstile, fingerprinting ו-behavioral, עם דוגמאות אינטגרציה ל-Next.js ולטופס Firebase.
למי זה מתאים: בעלי אתרים שראו spam מתגנב לטפסים גם אחרי שהוסיפו reCAPTCHA, ומפתחים שמבינים שהמשחק של הגנה מבוטים השתנה ב-2026. אם הטופס שלך מקבל לידים שמתחזים לאמיתיים, או שה-API שלך נסחף בקריאות לא צפויות מ-headless browsers — המדריך הזה מסביר מה השתנה ומה החליף את הפתרונות הישנים.
למה reCAPTCHA נשבר
ב-2018, reCAPTCHA v3 היתה הגנה רצינית. הרעיון: ניקוד התנהגותי שקט (0.0-1.0), בלי תיבת ״אני לא רובוט״, בלי תמונות של אופנועים. אם המשתמש קיבל מתחת ל-0.5 — חשוד, אם מעל — אנושי.
זה עבד היטב כל עוד הבוטים היו סקריפטים פשוטים שעובדים על HTTP. אבל ב-2023-2024 משהו השתנה: headless browsers הפכו לסטנדרט. Playwright ו-Puppeteer חינמיים, ויש להם stealth plugins שמסירים כמעט כל סימן זיהוי. ואז ב-2024-2025 הגיעו AI agents — Claude עם computer use, ChatGPT עם Operator, browser-use של LangChain — שמפעילים דפדפן אמיתי במלוא הריצה, מקליקים כמו בני אדם, ממלאים טפסים בקצב טבעי, ואפילו פותרים CAPTCHAs ויזואליים בדיוק של 90%+.
תוצאה: דוח ה-Bad Bot של Imperva לשנת 2025 מצא שלראשונה מזה עשור תעבורה אוטומטית עברה את התעבורה האנושית — 51% מכלל תעבורת האינטרנט. מתוך זה, 37% מכלל התעבורה הם bad bots עם כוונות שליליות. כל אתר עם טופס פתוח, כל API ציבורי — מקבל הצפה. הדוח גם מצביע על כך ש-GenAI הוריד את רף הכניסה: גם תוקפים לא מתוחכמים יכולים היום לשגר נפח גבוה של מתקפות בתדירות גבוהה.
הבעיה היא לא רק כמות. זו בעיה איכותית חדשה:
- Bots לגיטימיים — Google, Bingbot, AI agents שעובדים עבור משתמש אמיתי (אתה רוצה ש-Claude שלך יקליק על ״קנה״ בשמך? כן, אם הוא שלך).
- AI scrapers זדוניים — scrapers שגונבים תוכן לאימון מודלים בלי לכבד robots.txt, אלפי בוטים שמושכים את כל האתר.
- Traditional bots — credential stuffing, scalping, spam.
reCAPTCHA לא מבדיל בין השלושה. הוא רואה ״headless browser״ וחוסם הכל. זה אומר שבוט לגיטימי של המשתמש שלך נחסם, ובו בזמן bot זדוני עם stealth עובר בלי בעיה.
ארכיטקטורה חדשה — שכבות, לא חומה אחת
הגישה ב-2026 היא לא לסמוך על מנגנון אחד, אלא לבנות שכבות. כל שכבה תופסת סוג שונה של איום, ואם משהו עובר את אחת — השאר יתפסו.
שכבה 1 — Rate Limiting. הפשוטה ביותר. כל IP יכול לקרוא לטופס יצירת הקשר X פעמים בשעה. עוצרת bots פרימיטיביים שעובדים על נפח. Upstash או Vercel KV עם token bucket. עלות: סנטים בחודש. צריך בכל אתר.
שכבה 2 — Fingerprinting. איסוף סימנים מהדפדפן: user agent, canvas signature, fonts, WebGL renderer, plugins. FingerprintJS Pro הוא הסטנדרט; חלופה חינמית-יחסית היא Botd (open source). עוצר bots שמשתמשים באותו דפדפן/setup לכמה מתקפות.
שכבה 3 — Behavioral. ניתוח של איך המשתמש זז: תנועות עכבר, מהירות הקלדה, focus events, scroll patterns. בוט שמקליק בדיוק במרכז הכפתור עם delay של 0ms — בולט. ספקים: HUMAN (לשעבר PerimeterX), DataDome.
שכבה 4 — Attestation. מאמת שהבקשה מגיעה מסביבה אמיתית. זה היה החלק החדש ב-2025-2026. Vercel BotID (GA יוני 2025), Cloudflare Turnstile, Apple Private Access Tokens. זה כמעט תמיד המחליף של reCAPTCHA.
שכבה 5 — Identity-based. אם המשתמש מחובר עם OAuth/אימייל מאומת, מתייחסים אליו אחרת. כאן נכנס גם הזיהוי של AI agent חתום — להבדיל בין סוכן שפועל בשם משתמש אמיתי לבין bot זר (נרחיב על כך בהמשך).
לטופס תדמיתי בדרך כלל שכבות 1+4 מספיקות. ל-SaaS עם משתמשים — מוסיפים 2+3. לפלטפורמת ecommerce שמטרה לתקיפות — כל החמש.
אם אתה בונה SPA קלאסי (React/Vite) ולא Next.js, כדאי לקרוא גם את react-spa-seo — חלק מאותם שיקולי SSR משפיעים גם על איפה אתה מבצע את ה-attestation (לקוח מול שרת).
Vercel BotID — מה זה ולמה זה מעניין
Vercel BotID יצא GA ביוני 2025. הרעיון מנוסח בבלוג שלהם: ״invisible CAPTCHA״ — אין UI, אין צ׳אלנג׳ למשתמש, רק verification ברקע. שכבת ה-Deep Analysis שלו מופעלת בפועל על תשתית של Kasada (חברת anti-bot ותיקה), אבל היא משולבת כשכבה מקומית של Vercel — אתה לא מתממשק ישירות מול Kasada.
איך זה עובד טכנית: ה-SDK מטמיע snippet קטן בצד הלקוח. הסניפט אוסף סדרת אותות (fingerprint, behavioral, network) ושולח אותם לתשתית של Vercel. בשרת אתה קורא ל-checkBotId(), וזו מחזירה החלטה (isBot/isHuman, ובמצב verified-bot גם isVerifiedBot, verifiedBotName ו-verifiedBotCategory). ה-API שלך מחליט מה לעשות עם התשובה.
ל-BotID יש שתי רמות, וחשוב להבין את ההבדל כי הוא משפיע ישירות על החיוב:
| רמה | מה היא בודקת | חיוב |
|---|---|---|
| Basic | תקינות וקוהרנטיות של ה-challenge response. תופס בוטים פחות מתוחכמים. | חינם בכל התוכניות, כולל Hobby |
| Deep Analysis | ניתוח ML של אלפי אותות מצד הלקוח (powered by Kasada). תופס bot networks מתוחכמים. | זמין ב-Pro ו-Enterprise. כ-1$ לכל 1,000 קריאות ל-checkBotId() שמפעילות Deep Analysis. צפיות עמוד או בקשות שלא קוראות לפונקציה לא מחויבות |
יתרונות:
- Invisible — שום פאזל למשתמש, שום delay מורגש.
- Basic חינמי לחלוטין בכל התוכניות. אתה משלם רק כשאתה מפעיל Deep Analysis בפועל, ורק על הקריאות עצמן.
- אינטגרציה של דקות עם Next.js (וגם עם פריימוורקים אחרים שרצים על Vercel).
- מטפל ב-AI agents לגיטימיים — מתחזק directory של בוטים מוכרים (כולל ChatGPT Operator וכו׳) ומאמת אותם דרך IP, reverse DNS וגם Web Bot Authentication (חתימות קריפטוגרפיות).
חסרונות:
- רק בפרויקטים ב-Vercel. אם האתר שלך ב-Firebase או ב-Cloudflare Pages — לא רלוונטי (ראה את vercel-vs-firebase-hosting אם אתה מתלבט איפה לארח).
- Black box — אתה לא תמיד רואה בדיוק למה בקשה סווגה כבוט.
- חיוב על Deep Analysis מצטבר אם יש לך נפח גבוה של קריאות מאומתות.
דוגמה 1 — BotID בטופס Next.js
הסטאפ פשוט. נניח שיש לך App Router עם Route Handler שמקבל פניה (אם אתה עדיין על גרסה ישנה, שווה לקרוא קודם את nextjs-16-app-router):
npm install botid
ראשית מגדירים את ה-proxy ב-next.config כך שה-snippet יוגש מהדומיין שלך (זה מונע שבוטים יזהו וירמו את ה-endpoint):
// next.config.ts
import { withBotId } from 'botid/next/config';
const nextConfig = {
// שאר ההגדרות שלך
};
export default withBotId(nextConfig);
קומפוננטה צד-לקוח שעוטפת את הטופס:
// app/contact/ContactForm.tsx
'use client';
import { useState } from 'react';
import { initBotId } from 'botid/client/core';
// טוען את ה-snippet פעם אחת לדף, ומגן על ה-path של ה-API
initBotId({ protect: [{ path: '/api/contact', method: 'POST' }] });
export default function ContactForm() {
const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle');
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setStatus('sending');
const data = new FormData(e.currentTarget);
// fetch רגיל — ה-snippet מצרף את ה-BotID token אוטומטית לבקשה המוגנת
const res = await fetch('/api/contact', {
method: 'POST',
body: JSON.stringify(Object.fromEntries(data)),
headers: { 'Content-Type': 'application/json' },
});
setStatus(res.ok ? 'sent' : 'error');
}
return (
<form onSubmit={onSubmit} dir="rtl" className="space-y-3">
<input name="name" placeholder="שם מלא" required />
<input name="email" type="email" placeholder="אימייל" required />
<textarea name="message" placeholder="הודעה" required />
<button disabled={status === 'sending'}>
{status === 'sending' ? 'שולח...' : 'שלח'}
</button>
{status === 'sent' && <p>תודה, נחזור אליך</p>}
{status === 'error' && <p>שגיאה — נסה שוב</p>}
</form>
);
}
ב-Route Handler מאמתים את ה-token:
// app/api/contact/route.ts
import { checkBotId } from 'botid/server';
import { NextResponse } from 'next/server';
export async function POST(req: Request) {
const verification = await checkBotId();
// חוסמים בוט — אבל מאפשרים סוכן מאומת לגיטימי לעבור
if (verification.isBot && !verification.isVerifiedBot) {
return NextResponse.json(
{ error: 'Bot detected' },
{ status: 403 },
);
}
const body = await req.json();
// המשך עיבוד הטופס — שמירה ב-DB, שליחת אימייל וכו'
// ...
return NextResponse.json({ ok: true });
}
זה הכל. הסניפט בצד הלקוח אוסף את האותות, ה-API מאמת בשרת. אין שום UI נוסף למשתמש, ובוטים שנפלו נחסמים שקט. שים לב: isVerifiedBot מאפשר לך להעביר במכוון Googlebot או סוכן AI חתום בלי לחסום אותם — מה שמחזיר אותנו לבעיה האיכותית שדיברנו עליה.
חשוב לדעת: Basic רץ חינם בכל התוכניות ותופס את רוב הבוטים הפשוטים. Deep Analysis מופעל רק כשאתה קורא ל-checkBotId() במצב המתאים, ומחויב פר קריאה. לרוב הטפסים התדמיתיים, Basic מספיק; שמור את Deep Analysis ל-endpoints יקרי-ערך (login, תשלום, יצירת חשבון).
כשאתה לא ב-Vercel — Cloudflare Turnstile
Vercel BotID יפה למי שב-Vercel. אם האתר שלך ב-Firebase (כמו nisai.dev), ב-Netlify, או על שרת רגיל — Cloudflare Turnstile הוא המקבילה הקרובה ביותר. הוא חינמי לחלוטין, ללא הגבלת נפח לתוכנית החינמית. נכון לרבעון 2 2026, Cloudflare ממליצים על Turnstile גם למי שלא משתמש ב-Cloudflare כ-CDN — זה עצמאי.
Turnstile מציע שלושה מצבים:
- Managed (מומלץ) — Cloudflare מחליטים אם להציג challenge למשתמש או לעשות הכל ברקע. רוב המשתמשים לא יראו כלום.
- Non-interactive — תמיד ברקע, אבל יותר חסם (ייתכן יותר false negatives).
- Invisible — אפילו לא widget; המשתמש לא רואה דבר.
נכתוב אינטגרציה לטופס Firebase. בצד לקוח React:
<!-- index.html — טוען את הסקריפט פעם אחת -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async defer></script>
// src/components/ContactForm.tsx
import { useEffect, useRef, useState } from 'react';
import { httpsCallable } from 'firebase/functions';
import { functions } from '../lib/firebase';
declare global {
interface Window {
turnstile: {
render: (el: string | HTMLElement, opts: TurnstileOptions) => string;
reset: (widgetId: string) => void;
};
}
}
interface TurnstileOptions {
sitekey: string;
callback: (token: string) => void;
'error-callback'?: () => void;
}
export function ContactForm() {
const widgetRef = useRef<HTMLDivElement>(null);
const widgetIdRef = useRef<string | null>(null);
const [token, setToken] = useState<string | null>(null);
const [busy, setBusy] = useState(false);
// טען widget פעם אחת
useEffect(() => {
if (!widgetRef.current || widgetIdRef.current) return;
const id = window.turnstile.render(widgetRef.current, {
sitekey: import.meta.env.VITE_TURNSTILE_SITE_KEY,
callback: (t) => setToken(t),
'error-callback': () => setToken(null),
});
widgetIdRef.current = id;
}, []);
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
if (!token) return alert('סיים אימות אנושי');
setBusy(true);
const data = new FormData(e.currentTarget);
const submitContact = httpsCallable(functions, 'submitContact');
await submitContact({
name: data.get('name'),
email: data.get('email'),
message: data.get('message'),
turnstileToken: token,
});
setBusy(false);
if (widgetIdRef.current) window.turnstile.reset(widgetIdRef.current);
setToken(null);
}
return (
<form onSubmit={onSubmit} dir="rtl">
<input name="name" placeholder="שם מלא" required />
<input name="email" type="email" placeholder="אימייל" required />
<textarea name="message" placeholder="הודעה" required />
<div ref={widgetRef} />
<button disabled={!token || busy}>שלח</button>
</form>
);
}
צד שרת — Firebase Cloud Function שמאמתת מול Cloudflare:
// functions/src/index.ts
import { onCall, HttpsError } from 'firebase-functions/v2/https';
import { defineSecret } from 'firebase-functions/params';
const TURNSTILE_SECRET = defineSecret('TURNSTILE_SECRET_KEY');
export const submitContact = onCall(
{ secrets: [TURNSTILE_SECRET], region: 'europe-west1' },
async (request) => {
const { name, email, message, turnstileToken } = request.data;
if (!turnstileToken) {
throw new HttpsError('failed-precondition', 'missing-token');
}
// אמת מול Cloudflare
const verify = await fetch(
'https://challenges.cloudflare.com/turnstile/v0/siteverify',
{
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
secret: TURNSTILE_SECRET.value(),
response: turnstileToken,
remoteip: request.rawRequest.ip ?? '',
}),
},
).then((r) => r.json());
if (!verify.success) {
throw new HttpsError('permission-denied', 'bot-detected');
}
// המשך עיבוד — שליחת אימייל, שמירה ב-Firestore וכו'
// ...
return { ok: true };
},
);
הגדרת ה-secret פעם אחת:
firebase functions:secrets:set TURNSTILE_SECRET_KEY
# מדביקים את ה-Secret Key מ-Cloudflare Dashboard
זה הכל. הטופס מקבל הגנה מבוטים בלי שהמשתמש יראה challenge ברוב המקרים, ובלי תשלום ל-Cloudflare. אם אתה רוצה להעמיק במנגנון שליחת המייל עצמו אחרי האימות, יש לי מדריך נפרד: contact-forms-emailjs-resend.
reCAPTCHA, Turnstile ו-BotID — השוואה ישירה
זו ההחלטה שאנשים הכי מתלבטים עליה. השוואה תכל׳ס נכון ל-2026:
| reCAPTCHA v3 | Cloudflare Turnstile | Vercel BotID | |
|---|---|---|---|
| מחיר | חינם (Enterprise בתשלום) | חינם, ללא הגבלת נפח | Basic חינם בכל התוכניות; Deep Analysis בתשלום פר קריאה |
| חוויית משתמש | invisible (ניקוד) | רוב הזמן invisible (Managed) | invisible לגמרי |
| עמידות מול AI agents | חלשה — נשבר ע״י stealth | בינונית-טובה | טובה (Deep Analysis + verified bots) |
| תלות בפלטפורמה | אין | אין (עצמאי מה-CDN) | רק Vercel |
| פרטיות | נתונים ל-Google | טוב יותר (Cloudflare לא מבסס פרסום) | נתונים ל-Vercel/Kasada |
| מתי לבחור | אתר WordPress/legacy שכבר עליו | כל אתר שלא ב-Vercel (Firebase, Netlify, שרת) | אפליקציה שכבר רצה על Vercel |
הכלל הפרקטי: לא ב-Vercel? Turnstile. ב-Vercel? BotID. reCAPTCHA v3 כברירת מחדל היחידה רק אם אתה כבול ל-WordPress או למערכת ישנה שכבר מובנית סביבו, ואז עדיף לעטוף אותו בשכבת rate limiting + honeypot.
Honeypot ו-timing — השכבה החינמית שאף אחד לא מטמיע
לפני שאתה בכלל קורא ל-attestation, יש שתי בדיקות שעולות אפס ותופסות נתח מכובד מהבוטים הפשוטים: honeypot ו-time-to-submit. הן לא מחליפות את BotID או Turnstile, אבל הן מסננות נפח לפני שאתה משלם על Deep Analysis או על קריאת siteverify.
Honeypot הוא שדה טופס שמוסתר מבני אדם (לא דרך type="hidden", שבוטים מזהים, אלא דרך CSS שמוציא אותו מהמסך). משתמש אמיתי לא רואה אותו ולכן משאיר אותו ריק. בוט פשוט שממלא כל שדה שהוא מוצא ב-DOM ימלא גם אותו. Time-to-submit מודד כמה זמן עבר מטעינת הטופס ועד השליחה: בן אדם צריך לפחות 2-3 שניות לקרוא ולהקליד, בוט שולח תוך מילי-שניות.
// honeypot + timestamp בצד הלקוח
const formLoadedAt = useRef(Date.now());
// בתוך הטופס — שדה שמוחבא מהעין ומ-screen readers
<input
type="text"
name="company" // שם מפתה לבוט (״חברה״)
tabIndex={-1}
autoComplete="off"
aria-hidden="true"
style={{ position: 'absolute', left: '-9999px', height: 0 }}
/>
<input type="hidden" name="ts" value={formLoadedAt.current} />
// בצד השרת — לפני attestation
const filledHoneypot = body.company && body.company.length > 0;
const elapsed = Date.now() - Number(body.ts);
if (filledHoneypot || elapsed < 2000) {
// נראה כמו בוט — אפשר להחזיר 200 ״הצלחה״ מזויפת
// כדי לא ללמד את הבוט שנתפס
return NextResponse.json({ ok: true });
}
טריק קטן ששווה זהב: כשאתה תופס בוט ב-honeypot, אל תחזיר שגיאה. החזר תשובת הצלחה מזויפת. כך הבוט חושב שהוא עבר, לא מנסה וריאציות אחרות, וה-spam פשוט נופל לחור שחור. הבדיקה הזו, יחד עם rate limiting, מורידה את עומס ה-Deep Analysis ולכן גם את העלות. שים לב ש-aria-hidden ו-tabIndex={-1} קריטיים כאן: בלעדיהם, משתמש מקלדת או קורא-מסך עלול ״ליפול״ לתוך שדה ה-honeypot ולמלא אותו בטעות, מה שיחסום משתמש אמיתי. אם אתה לא בטוח שהטופס שלך נגיש כמו שצריך, יש לי מדריך נפרד על rtl-accessibility-hebrew.
כשמותר ל-AI agent לעבור
ב-2026 השאלה הזו נכנסה לקדמת הבמה. אם הלקוח שלך משתמש ב-Claude שלו כדי למלא טפסים בשמו — אתה לא רוצה לחסום אותו. איך מבדילים בין סוכן לגיטימי לבין bot זר? יש שלוש גישות שעלו:
1. זיהוי בוט מאומת (verified bot). ספקי attestation מודרניים מתחזקים directory של בוטים מוכרים ומאמתים את הזהות שלהם דרך כמה שכבות: בדיקת טווח ה-IP של מפעיל הבוט, reverse DNS שמחזיר חזרה לדומיין הצפוי, ו-Web Bot Authentication — חתימות קריפטוגרפיות שמוכיחות שהבקשה באמת הגיעה מהסוכן שהיא טוענת. ב-Vercel BotID זה חשוף דרך isVerifiedBot ו-verifiedBotName, וב-Cloudflare דרך Verified Bots. כך אתה יכול לתת ל-Googlebot או ל-ChatGPT Operator pass במכוון, ולחסום את כל השאר.
2. Allow-list ל-user agents ידועים + IP ranges. Anthropic, OpenAI ו-Google מפרסמים את ה-IP ranges וה-user agents של הסוכנים והקראולרים הרשמיים שלהם. אתה יכול לזהות סוכן כזה ולתת לו pass חלקי (rate limit אבל לא חסימה). זה לבדו לא חסין — אפשר לזייף user agent — אבל יחד עם אימות IP/DNS או חתימה זה אמין.
3. Per-action permission. במקום לחסום פעולה, להוסיף שלב אישור: AI ביצע פעולה, נשלח אימייל למשתמש: ״Claude שלך ביקש לבצע X — לאשר?״ המשתמש מאשר. מתאים לפעולות בעלות השפעה גבוהה (תשלום, מחיקה).
ההמלצה הפרקטית: לטופס יצירת קשר רגיל אל תטרח להבדיל, פשוט תאמת אנושיות עם BotID/Turnstile. ל-actions עם תוצאה כספית, שלב אישור per-action. אם אתה בכלל בונה סוכן AI שמבצע פעולות בשם משתמשים, כדאי לקרוא גם את ai-voice-agents-2026 ואת whatsapp-ai-agent — שם אותם שיקולי הרשאה והתחזות חוזרים מהצד השני של המתרס.
טעויות נפוצות
להישען רק על client-side validation. ה-token חייב להיות מאומת בשרת. אם תאמת בלקוח בלבד — בוט יזייף תוצאה ויעבור. זו הטעות מספר אחת, וקל ליפול בה כשממהרים.
לא להבדיל בין false positive ל-false negative. false negative (בוט עבר) מציק בלוגים. false positive (משתמש אמיתי נחסם) מוריד conversion ישירות. תרצה לוגים גם של מקרים נחסמים כדי לוודא שאתה לא חוסם משתמשים אמיתיים — אם אתה מודד המרות בכלל, ראה analytics-ga4-plausible-posthog על איך לסמן אירועי חסימה.
להוסיף הגנה רק לטפסים. בוטים תוקפים גם API endpoints, חיפוש, login. אם יש לך login עם passwords — תוסיף הגנה גם שם (credential stuffing).
לסמוך על reCAPTCHA v3 לבד ב-2026. Google עדיין תומכים, אבל הוא נחשב weak כלפי AI scrapers. אם זה מה שיש לך, תוסיף לפחות שכבת rate limiting + IP reputation.
להפעיל אגרסיבי מדי בהתחלה. הסטטיסטיקה של BotID/Turnstile עוזרת לכייל. תרץ במצב ״log only״ שבוע-שבועיים, תראה כמה false positive יש לך, ואז תהפוך לחסימה.
להתעלם מ-honeypot כשכבה אפסית. שדה טופס נסתר (display:none) שבן אדם לעולם לא ימלא, אבל בוט פשוט כן — זה חינמי, לוקח 5 דקות, ותופס נפח לא מבוטל לפני שהבקשה בכלל מגיעה ל-attestation. לא מחליף את השכבות, אבל משלים אותן.
המלצה לפי תרחיש
| התרחיש | המלצה ב-2026 |
|---|---|
| טופס יצירת קשר ב-Vercel/Next.js | Vercel BotID — Basic חינם, אינטגרציה של דקות |
| טופס Firebase / Cloudflare Pages | Cloudflare Turnstile — חינמי, פשוט |
| טופס WordPress | reCAPTCHA v3 + honeypot + rate limit (ל-Turnstile יש plugin) |
| API ציבורי עם משתמשים | Turnstile/BotID + rate limit + JWT |
| SaaS עם login | BotID (Deep Analysis) + fingerprinting (FingerprintJS) + 2FA |
| Ecommerce תחת מתקפה | DataDome / HUMAN / Kasada — managed, יקר אבל יעיל |
שאלות נפוצות
האם reCAPTCHA עדיין שווה משהו ב-2026?
הוא עדיין עוצר נפח של בוטים פרימיטיביים, אז הוא לא חסר תועלת — אבל הוא לבדו כבר לא הגנה רצינית מול headless browsers עם stealth ו-AI agents. אם זה מה שכבר מותקן אצלך (למשל ב-WordPress), השאר אותו אבל הוסף מעליו שכבת rate limiting ו-honeypot. לאתר חדש, BotID או Turnstile עדיפים על reCAPTCHA v3.
Vercel BotID עולה כסף?
הרמה ה-Basic חינמית לחלוטין בכל התוכניות, כולל Hobby, ותופסת את רוב הבוטים הפשוטים. אתה משלם רק על Deep Analysis, שזמין בתוכניות Pro ו-Enterprise ומחויב בערך 1$ לכל 1,000 קריאות ל-checkBotId() שמפעילות את הניתוח העמוק. צפיות עמוד או בקשות שלא קוראות לפונקציה לא מחויבות, ולכן בפועל רוב הטפסים התדמיתיים נשארים בחינם.
האם Cloudflare Turnstile עובד אם האתר שלי לא על Cloudflare?
כן. Turnstile עצמאי מה-CDN — אתה יכול להריץ אתר ב-Firebase Hosting, Netlify או שרת רגיל ועדיין להשתמש בו. אתה מוסיף את ה-script של Cloudflare בצד הלקוח ומאמת את ה-token מול endpoint ה-siteverify בצד השרת, בדיוק כמו בדוגמת ה-Firebase במדריך.
איך אני נותן ל-AI agent לגיטימי לעבור בלי לחסום בוטים זרים?
משתמשים בזיהוי בוט מאומת. ספקי attestation מתחזקים directory של סוכנים מוכרים ומאמתים את הזהות שלהם דרך טווחי IP, reverse DNS ו-Web Bot Authentication (חתימות קריפטוגרפיות). ב-Vercel BotID זה חשוף דרך isVerifiedBot ו-verifiedBotName, כך שאתה יכול להעביר במכוון סוכן חתום ולחסום את כל היתר. לפעולות כספיות, הוסף שלב אישור per-action.
למה חשוב לאמת את ה-token בצד השרת ולא רק בלקוח?
כי כל מה שרץ בלקוח אפשר לזייף או לעקוף. בוט יכול לדלג על קוד הלקוח לחלוטין ולשלוח בקשה ישירות ל-API שלך עם token מזויף. רק אימות בצד השרת — מול ה-endpoint של Vercel או של Cloudflare — נותן תשובה אמינה אם הבקשה אנושית. זו הטעות הכי נפוצה ביישומי הגנה מבוטים.
כמה שכבות הגנה אני באמת צריך?
תלוי בסיכון. לטופס יצירת קשר תדמיתי, rate limiting + attestation (שכבות 1+4) מספיקות. ל-SaaS עם login הוסף fingerprinting ו-behavioral (2+3). רק לפלטפורמת ecommerce שנמצאת תחת מתקפה אמיתית כדאי לפרוס את כל חמש השכבות, לרוב עם ספק managed כמו DataDome או HUMAN. אל תבנה מבצר סביב טופס שמקבל שלוש פניות ביום.
לסיכום
הגנה מבוטים ב-2026 כבר לא נשענת על reCAPTCHA. כשמחצית מתעבורת האינטרנט אוטומטית ו-AI agents מקלידים ומקליקים כמו בני אדם, הניקוד ההתנהגותי של reCAPTCHA v3 פשוט לא מבדיל. הגישה שעובדת היא שכבות: rate limiting בבסיס, attestation invisible (BotID אם אתה ב-Vercel, Turnstile אם לא) כשכבה המרכזית, ועוד fingerprinting/behavioral לפי הסיכון. אמת תמיד בצד השרת, הרץ במצב log-only לפני שאתה חוסם, והבחן בין סוכן AI לגיטימי לבין bot זר במקום לחסום הכל בגזירה. לרוב האתרים — טופס תדמיתי או SaaS קטן — שתי שכבות נכונות מורידות 99% מה-spam בלי לפגוע במשתמש אמיתי אחד.
למי לפנות
אם הטופס שלך מקבל spam ולא בטוח איזו שכבה מתאימה לסטאק שלך, או שאתה רוצה לעבור מ-reCAPTCHA לדבר שעובד באמת — שלח לי הודעה דרך טופס יצירת הקשר או ב-WhatsApp ב-wa.me/972585802298. בדרך כלל מספיק שעה כדי להבין מה הסטאק וההמלצה הקונקרטית.
מקורות
- Vercel — BotID announcement (June 2025)
- Vercel BotID — Documentation
- Vercel — BotID Deep Analysis catches a sophisticated bot network
- Kasada — The Best CAPTCHA is No CAPTCHA: Vercel BotID
- Cloudflare Turnstile — Documentation
- Cloudflare Turnstile — Getting Started
- Imperva — 2025 Bad Bot Report
- OWASP — Automated Threats to Web Applications
- Anthropic — Claude for Chrome
- Google — Verifying Googlebot and other Google crawlers
- HUMAN Security — Bot Defender