Preskočiť na obsah
Bezpečnosť PHP 14. júl 2026 · 12 min čítania

Ochrana API proti botom a AI crawlerom

AI crawlery ako GPTBot, ClaudeBot či PerplexityBot neberú ohľad na robots.txt pri prístupe k API endpointom — a bežné scraping boty nikdy nebrali. Ak vaše API vracia dáta bez overenia, niekto ich práve zbiera. Tento článok ukáže, ako zabezpečiť API vrstvami: od rate limitingu cez Cloudflare WAF po honeypot endpointy.

DC

Dušan Chlpek

PHP vývojár, GEAR s.r.o. · 25+ rokov praxe

Prečo tradičná ochrana nestačí

Klasické riešenia ako robots.txt a CAPTCHA chránili weby pred starými generáciami crawlerov. API endpointy sú iná situácia: odpovedajú strojovo čitateľnými dátami (JSON/XML) bez vizuálneho rozhrania, takže CAPTCHA nie je použiteľná. Súbor robots.txt je neformálna dohoda — bot ho môže jednoducho ignorovať a zákon mu v tom nezabráni. AI crawlery (GPTBot, ClaudeBot, PerplexityBot, Bytespider, CCBot) navyše pristupujú k endpointom priamo cez HTTP bez akejkoľvek autentifikácie. Ochrana API musí byť aktívna, nie pasívna.

Efektívna ochrana sa skladá z niekoľkých vrstiev, ktoré sa vzájomne dopĺňajú:

  1. Rate limiting — obmedzenie počtu požiadaviek za čas
  2. Autentifikácia — overenie totožnosti klienta
  3. Detekcia botov — identifikácia podľa User-Agent a správania
  4. Sieťová vrstva (Cloudflare) — blokovanie ešte pred serverom
  5. Honeypot endpointy — pasca na automatizované skenery
  6. Logovanie — viditeľnosť do toho, čo sa deje

Rate limiting v Laraveli

Rate limiting je prvá a najdôležitejšia vrstva. Laravel od verzie 8 ponúka RateLimiter facade, ktorý umožňuje definovať vlastné limity pre API endpointy priamo v kóde.

Vlastný limiter pre API

V súbore app/Providers/AppServiceProvider.php (alebo RouteServiceProvider.php) definujte limiter:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;

RateLimiter::for('api', function (Request $request) {
    return $request->user()
        ? Limit::perMinute(120)->by($request->user()->id)
        : Limit::perMinute(30)->by($request->ip());
});

RateLimiter::for('ai-sensitive', function (Request $request) {
    return Limit::perHour(10)->by($request->ip())
        ->response(function () {
            return response()->json([
                'error' => 'Prekročený limit požiadaviek.',
                'retry_after' => 3600,
            ], 429);
        });
});

V routes súbore priraďte middleware k endpointom:

Route::middleware(['throttle:api'])->group(function () {
    Route::get('/products', [ProductController::class, 'index']);
    Route::get('/products/{id}', [ProductController::class, 'show']);
});

Route::middleware(['throttle:ai-sensitive'])->group(function () {
    Route::get('/export/all', [ExportController::class, 'all']);
});
Tip: Pre ukladanie rate limit počítadiel použite Redis namiesto predvoleného file cache — je rádovo rýchlejší pri vysokom počte súbežných požiadaviek. Nastavte CACHE_STORE=redis.env.

Rate limiting v Nginxe (pred PHP)

Nginx dokáže obmedziť požiadavky ešte pred tým, ako sa dostanú k PHP — nulové zaťaženie PHP-FPM pri útoku:

http {
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/m;

    server {
        location /api/ {
            limit_req zone=api_limit burst=10 nodelay;
            limit_req_status 429;
            try_files $uri $uri/ /index.php?$query_string;
        }
    }
}

Kombinujte Nginx rate limiting s Laravelom: Nginx zastaví hrubé útoky, Laravel spravuje jemnozrnné limity podľa používateľa alebo API kľúča.

Blokovanie AI crawlerov podľa User-Agent

AI crawlery sa vo väčšine prípadov identifikujú vlastným User-Agent reťazcom — GPTBot, ClaudeBot, PerplexityBot a ďalšie. Blokovanie podľa User-Agent je prvá rýchla vrstva ochrany, aj keď nie je neprekonateľná (bot môže User-Agent falšovať).

Middleware pre blokovanie botov v Laraveli

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class BlockAiCrawlers
{
    private const BLOCKED_AGENTS = [
        'gptbot', 'chatgpt-user', 'claudebot', 'claude-web',
        'perplexitybot', 'bytespider', 'ccbot', 'amazonbot',
        'anthropic-ai', 'cohere-ai', 'diffbot', 'omgili',
        'facebookexternalhit',
    ];

    public function handle(Request $request, Closure $next): mixed
    {
        $userAgent = strtolower($request->userAgent() ?? '');

        foreach (self::BLOCKED_AGENTS as $blocked) {
            if (str_contains($userAgent, $blocked)) {
                return response()->json([
                    'error' => 'Automated access is not permitted.',
                ], 403);
            }
        }

        return $next($request);
    }
}

Zaregistrujte middleware v bootstrap/app.php (Laravel 11+) a aplikujte na API routes:

Route::middleware(['throttle:api', \App\Http\Middleware\BlockAiCrawlers::class])
    ->prefix('api')
    ->group(base_path('routes/api.php'));
Pozor: Blokovanie podľa User-Agent je ľahko obíditeľné — sofistikovaný bot môže predstierať bežný prehliadač. Preto túto vrstvu nikdy nepoužívajte ako jedinú ochranu, ale vždy v kombinácii s autentifikáciou a rate limitingom.

Cloudflare WAF: blokovanie pred serverom

Cloudflare stojí pred vaším serverom a môže blokovať boty ešte pred tým, ako sa požiadavka dostane k Nginxu alebo PHP. Pre API endpointy odporúčam dve pravidlá.

Pravidlo 1: blokovanie známych AI crawlerov

V Cloudflare dashboarde pod Security → WAF → Custom rules vytvorte pravidlo:

(http.user_agent contains "GPTBot") or
(http.user_agent contains "ClaudeBot") or
(http.user_agent contains "PerplexityBot") or
(http.user_agent contains "Bytespider") or
(http.user_agent contains "CCBot") or
(http.user_agent contains "anthropic-ai")

Akcia: Block

Pravidlo 2: Managed Challenge pre podozrivé požiadavky na API

Pre citlivé endpointy, kde boty nemajú čo hľadať, ale legítni klienti áno:

(http.request.uri.path matches "^/api/export") and
(not cf.client.bot) and
(not ip.src in $trusted_ips)

Akcia: Managed Challenge

Managed Challenge od Cloudflare je nenápadný — pre skutočného používateľa (prehliadač) beží na pozadí, bot ho nevyrieši.

Rate limiting v Cloudflare

Cloudflare Rate Limiting (Security → Rate Limiting) pridá ďalšiu vrstvu pred serverom — napríklad max. 100 požiadaviek za 10 sekúnd z jednej IP na /api/*. Efektívne pri DDoS útokoch, kde ani Nginx nestíha.

API autentifikácia a IP allowlisting

Verejné API bez akejkoľvek autentifikácie je pozvánka pre scrapery. Aj minimálna autentifikácia výrazne zredukuje automatizovaný prístup.

API tokeny (Bearer auth)

Laravel Sanctum vydáva tokeny pre každého klienta — každý prístup je spätne dohľadateľný:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens;
}

// Vydanie tokenu
$token = $user->createToken('client-app', ['read:products'])->plainTextToken;

// Overenie v middleware
Route::middleware('auth:sanctum')->get('/products', ...);

IP allowlisting pre B2B integrácie

Pre interné systémy alebo B2B partnerov, kde je IP adresa stabilná, pridajte IP allowlist ako ďalšiu vrstvu:

class IpAllowlist
{
    private const ALLOWED = ['203.0.113.10', '198.51.100.0/24'];

    public function handle(Request $request, Closure $next): mixed
    {
        foreach (self::ALLOWED as $range) {
            if ($this->ipInRange($request->ip(), $range)) {
                return $next($request);
            }
        }
        return response()->json(['error' => 'Forbidden'], 403);
    }

    private function ipInRange(string $ip, string $range): bool
    {
        if (!str_contains($range, '/')) {
            return $ip === $range;
        }
        [$subnet, $bits] = explode('/', $range);
        return (ip2long($ip) >> (32 - (int)$bits)) === (ip2long($subnet) >> (32 - (int)$bits));
    }
}

Prečo robots.txt nechráni API

robots.txt je neformálna dohoda, nie technická bariéra. Pravidlo Disallow: /api/ komunikuje zámer, ale nevynucuje ho — HTTP server odpovedá na každú požiadavku bez ohľadu na obsah robots.txt. Boty, ktoré chcú scrapeovať, jednoducho tento súbor ignorujú. Napriek tomu ho nevynechávajte: legitímne vyhľadávače ako Googlebot ho rešpektujú, čo šetrí crawl budget pre dôležitejšie stránky.

Chyba č. 1: „Máme /api/robots.txt ako Disallow, takže sme chránení." — Nie ste. robots.txt nechráni API. Vyžaduje sa technická vrstva ochrany.

Honeypot endpointy

Honeypot endpoint je falošná „pasca" — URL, ktorá nevyzerá legitímne pre človeka, ale automatizovaný skener ju navštívi, pretože prehľadáva všetky adresy. Akákoľvek požiadavka na honeypot endpoint automaticky zaradí IP adresu na čiernu listinu.

Route::any('/api/internal/debug', function (Request $request) {
    $ip = $request->ip();
    $ua = $request->userAgent();

    Log::channel('security')->warning('Honeypot hit', [
        'ip' => $ip,
        'user_agent' => $ua,
        'url' => $request->fullUrl(),
    ]);

    cache()->put("blocked_ip:{$ip}", true, now()->addHours(24));

    return response()->json(['error' => 'Not Found'], 404);
});

Middleware pre kontrolu čiernej listiny IP adries:

public function handle(Request $request, Closure $next): mixed
{
    if (cache()->has("blocked_ip:{$request->ip()}")) {
        return response()->json(['error' => 'Forbidden'], 403);
    }
    return $next($request);
}

Pridajte niekoľko honeypot URL adries, ktoré vyzerajú lákavo pre scrapery: /api/v1/admin/users, /api/dump, /api/export/full. Skutočné endpointy dokumentujte — len legitímni klienti, ktorí čítajú dokumentáciu, ich budú vedieť obísť.

Logovanie podozrivých vzorov

Bez logovania ste slepí — neviete, koľko botov pristupuje k API ani odkiaľ prichádzajú. Minimálny logging pre bezpečnostný audit:

class ApiSecurityLogger
{
    public function logSuspicious(Request $request, string $reason): void
    {
        Log::channel('security')->warning('Suspicious API request', [
            'reason' => $reason,
            'ip' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'method' => $request->method(),
            'url' => $request->path(),
            'rate_limit_remaining' => $request->header('X-RateLimit-Remaining'),
        ]);
    }
}

Čo logovať:

Tip: Presmerujte bezpečnostné logy do Slacku alebo e-mailu cez Laravel notification — pri väčšom počte podozrivých udalostí za hodinu dostanete okamžité upozornenie. Kanál security nakonfigurujte v config/logging.php so separátnym súborom, napríklad storage/logs/security.log.

llms.txt a dobrovoľné vymedzenie pre AI

Súbor /llms.txt v roote domény je vznikajúci štandard (analogický ku robots.txt), ktorý hovorí AI systémom, čo môžu použiť na trénovanie a čo nie. Pridáva sa ako doplnok k technickým opatreniam — väčšina eticky spravovaných AI crawlerov ho bude rešpektovať. Technickú ochranu však nenahradí.

Záver: desaťbodový checklist

Potrebujete zabezpečiť API alebo webovú aplikáciu?

Implementujem rate limiting, autentifikáciu aj Cloudflare WAF na mieru — s dôrazom na bezpečnosť bez dopadu na legitímnych klientov. Dopyt bez záväzkov, odpoveď do 24 hodín.

Ďalšie články

Zavolať E-mail Dopyt

Ochrana súkromia

Táto stránka využíva cookies pre nevyhnutné fungovanie. Rešpektujeme vaše súkromie a legislatívu GDPR.