Shield Corev1.2.x
Deteksi Perilaku
Rule mengenali request yang terlihat berbahaya. Perilaku mengenali pola — dan itu yang tidak bisa dilakukan satu request saja.
Scanner otomatis selalu mengirim ratusan request dan setiap kelihatan wajar. Yang membedakannya adalah request ke-101, ke-102, dan seterusnya, ke URL yang saling tidak berhubungan.
Dua lapis yang terpisah
Section titled “Dua lapis yang terpisah”| Lapis | Sumber | Cukup satu request? |
|---|---|---|
| Signature | Rule | Ya. |
| Perilaku | Counter dalam jendela waktu | Tidak. |
BehaviorDetector menerima counter yang sudah dihitung adapter dari cache,
lalu mengubahnya menjadi BehaviorReport:
$report = $behavior->evaluate($context, $normalized, $counters, $config);
$report->totalDelta; // jumlah skor$report->signals; // nama sinyal yang aktif$report->knownCrawler; // nama bot, kalau terdeteksiTabel lengkap sinyal
Section titled “Tabel lengkap sinyal”| Sinyal | Pemicu | Skor |
|---|---|---|
unique_uri_burst |
URI berbeda melewati unique_uri_limit (25) |
12 |
not_found_enumeration |
404 melewati not_found_limit (20) |
10 |
sensitive_path_burst |
Path sensitif melewati sensitive_path_rate_limit (8) |
10 |
path_rate_burst |
Path biasa melewati path_rate_limit (30) |
8 |
method_anomaly |
Method di luar GET, POST, HEAD, OPTIONS | 4 |
scanner_tool_ua |
User-Agent bernama scanner | 4 |
unverified_crawler_claim |
Mengaku bot, gagal diverifikasi | 4 |
missing_headers |
Tidak ada User-Agent | 2 |
suspicious_user_agent |
User-Agent generik atau ganjil | 2 |
missing_referer |
POST tanpa referrer | 2 |
oversized_request |
URI melewati batas panjang | 2 |
known_crawler |
Bot dikenali | 0 |
verified_crawler |
Bot diverifikasi lewat DNS | 0 |
Dua sinyal terakhir bernilai nol karena memang tidak menambah skor — tapi merekam fakta yang nanti dipakai mode bot.
Sinyal lemah dan mengapa ada
Section titled “Sinyal lemah dan mengapa ada”Tiga sinyal bernilai 2 dan itu disengaja:
missing_headers— beberapa klien sah tidak mengirim User-Agent.suspicious_user_agent—curl,wget, danpython-requestssangat umum, termasuk untuk integrator sah. Memblokirnya sendirian akan merusak.missing_referer— beberapa form memang tidak mengirim referrer.
Masing-masing bernilai 2, jadi tiga sinyal lemah itu masih di bawah lantai
CHALLENGE yang besarnya 10. Sinyal tanpa rule tidak akan pernah
membuat ban.
Inilah alasan RiskScorer memakai MIN_ESCALATION_BEHAVIOR_SCORE = 10 sebelum
menganggap perilaku sebagai pelanggaran yang layak menaikkan skor eskalasi.
scanner_tool_ua berbeda dari suspicious_user_agent
Section titled “scanner_tool_ua berbeda dari suspicious_user_agent”Keduanya membaca User-Agent, tapi bedanya jelas:
| Pemicu | Skor | |
|---|---|---|
scanner_tool_ua |
sqlmap, nikto, metasploit, wpscan, dirbuster, gobuster, masscan, nmap, nessus, acunetix, x00c, zgrab, httpx |
4 |
suspicious_user_agent |
curl/, wget, python-requests, scrapy, go-http-client, node-fetch, axios, okhttp, powershell, java/, dan Mozilla/5.0 polos |
2 |
Perbedaannya: orang yang menyebut tool scanner sedang berada di jalur yang
salah dan tahu apa yang dilakukan, sedangkan curl cuma klien HTTP biasa.
Mozilla/5.0 tanpa tambahan apa pun juga ditandai. Hampir tidak ada browser
sungguhan yang mengirim User-Agent persis seperti itu.
Path yang dilewati
Section titled “Path yang dilewati”Kalau path masuk skip_paths, seluruh perilaku dilewati:
'rules' => [ 'skip_paths' => ['/api/webhook/payment'],],Rule tetap berlaku — yang dimatikan hanya hitungan perilaku.
Alasannya terlihat di kode: counter di-key berdasarkan IP, sedangkan endpoint seperti OAuth atau gerbang antar layanan dipakai banyak klien sah sekaligus. Volume di sana bukan mencerminkan satu pelaku.
Perhatikan urutan elseif
Section titled “Perhatikan urutan elseif”if ($counters->isSensitivePath && $counters->pathRequestCount >= $config->sensitivePathRateLimit) { // 10 poin} elseif ($counters->pathRequestCount >= $config->pathRateLimit) { // 8 poin}Path yang sensitif hanya menghasilkan sensitive_path_burst. Ia tidak
sekaligus dapat path_rate_burst. Jadi 18, bukan 10 + 8.
Crawler terverifikasi mengembalikan nol
Section titled “Crawler terverifikasi mengembalikan nol”Ini bagian paling penting dari halaman ini. Kalau bot dikenali dan
verifikasi DNS berhasil, evaluate() langsung keluar:
return new BehaviorReport( totalDelta: 0, signals: [SIGNAL_KNOWN_CRAWLER, SIGNAL_VERIFIED_CRAWLER], knownCrawler: $knownCrawler,);Semua delta dinolkan, termasuk yang sudah dihitung sebelumnya. Googlebot sungguhan lalu boleh crawl agresif tanpa pernah tersentuh challenge atau ban, karena mengindeks memang butuh banyak request.
Kalau verifikasi gagal, yang terjadi justru sebaliknya: sinyal
unverified_crawler_claim sebesar 4, lalu mode bot yang memutuskan apa yang
dilakukan kepada crawler itu. Detailnya ada di
Verifikasi Crawler.
Counter yang harus Anda hitung sendiri
Section titled “Counter yang harus Anda hitung sendiri”BehaviorDetector tidak menghitung apa pun. Adapter Anda yang punya
tanggung jawab ini, dari cache:
use Ganadev\Shield\Core\Detection\BehaviorCounters;
$counters = new BehaviorCounters( uniqueUriCount: $cache->get("uri:{$ip}") ?? 0, notFoundCount: $cache->get("404:{$ip}") ?? 0, pathRequestCount: $cache->get("path:{$ip}:{$path}") ?? 0, isSensitivePath: $this->isSensitive($path),);Tiga counter pertama berbasis IP, yang ketiga per-path. Jendelanya
behavior.window_seconds, yang bawaannya 60 detik.
isSensitivePath bisa Anda ambil dari config.behavior.sensitive_paths.
Daftar default-nya /login, /wp-login.php, /admin/login,
/administrator/, /api/login, /api/auth, dan /user/login.
Menyesuaikan untuk traffic Anda
Section titled “Menyesuaikan untuk traffic Anda”Volume besar
Section titled “Volume besar”Kalau situs Anda punya traffic tinggi, satu IP bisa muncul sebagai “unique URI banyak” karena memang benar:
'behavior' => [ 'unique_uri_limit' => 60, 'not_found_limit' => 40,],Naikkan satu per satu dan lihat hasilnya di laporan.
Klien non-browser
Section titled “Klien non-browser”Kalau API Anda dipanggil dari browser, suspicious_user_agent tidak akan muncul
karena Accept dan User-Agent berasal dari klien yang sama. Kalau Anda punya
endpoint yang memang bukan halaman web, masukkan ke skip_paths.
Scanner sah
Section titled “Scanner sah”Tim keamanan internal Anda memindai situs sendiri? Jangan matikan
scanner_tool_ua secara global. allowlist.ips lebih tepat — perilaku
dimatikan untuk IP itu saja, signature tetap berlaku.
Yang perlu diingat
Section titled “Yang perlu diingat”Perilaku tidak pernah cukup untuk memblokir request pertama dari IP baru. Selalu ada dua lapis: signature untuk request ini, perilaku untuk history.
Kalau log Anda menunjukkan score_challenge tanpa matchedRuleIds apa pun,
itu perilaku murni. Buka Skor & Keputusan untuk
memahami kenapa itu terjadi dan bagaimana menanganinya.
Powered by PT Ganadev Multi Solusi