Konfigurasi
Semua opsi ada di config/shield.php (setelah publish). Semua punya default yang aman.
| Kunci | Env | Default | Keterangan |
|---|---|---|---|
enabled |
SHIELD_ENABLED |
true |
Aktif/nonaktif middleware. |
mode |
SHIELD_MODE |
observe |
observe | challenge | enforce. |
app_id |
SHIELD_APP_ID |
my-app |
Namespace cache & identitas aplikasi. |
response_code |
SHIELD_RESPONSE_CODE |
404 |
Kode respons blok (stealth). |
decode_depth |
— | 2 |
Maksimal dekode URL (0–3). |
fail_mode |
SHIELD_FAIL_MODE |
open |
open | closed saat infrastruktur mati. |
rule_version |
— | 1.0.0 |
Versi aturan (dicatat di event). |
Threshold & ban
Section titled “Threshold & ban”| Kunci | Default | Keterangan |
|---|---|---|
thresholds.challenge |
10 |
Skor mulai challenge. |
thresholds.ban |
20 |
Skor mulai ban sementara. |
thresholds.strong_ban |
30 |
Skor ban kuat. |
ban.durations |
[15, 60, 360, 1440] |
Durasi ban (menit) per offense 1..4+. |
escalation.step |
5 |
Tambahan skor per offense (maks 5 offense). |
Challenge
Section titled “Challenge”| Kunci | Env | Default | Keterangan |
|---|---|---|---|
challenge.driver |
SHIELD_CHALLENGE |
turnstile |
turnstile | recaptcha | null. |
challenge.turnstile.* |
SHIELD_TURNSTILE_* |
'' |
Site/secret key Turnstile. |
challenge.recaptcha.* |
SHIELD_RECAPTCHA_* |
'' |
Site/secret key reCAPTCHA. |
Perilaku
Section titled “Perilaku”| Kunci | Default | Keterangan |
|---|---|---|
behavior.unique_uri_limit |
25 |
Ambang burst URI unik per window. |
behavior.window_seconds |
60 |
Jendela waktu perilaku. |
behavior.not_found_limit |
20 |
Ambang enumerasi 404 per window. |
behavior.missing_referer_signal |
true |
Sinyal lemah POST tanpa Referer. |
behavior.suspicious_user_agents |
[] |
Marker UA scanner klien generic (sinyal +2). |
behavior.scanner_user_agents |
sqlmap, nikto, gobuster, … | Marker tool scanner (sinyal kuat scanner_tool_ua). |
behavior.scanner_ua_signal |
4 |
Skor sinyal tool scanner UA. |
behavior.path_rate_limit |
30 |
Ambang request per path umum. |
behavior.sensitive_path_rate_limit |
8 |
Ambang per path endpoint auth. |
behavior.sensitive_paths |
/login, /wp-login.php, … |
Endpoint auth yang dilindungi rate-limit lebih ketat. |
Bot / crawler
Section titled “Bot / crawler”| Kunci | Env | Default | Keterangan |
|---|---|---|---|
bots.mode |
SHIELD_BOT_MODE |
observe |
off | observe | challenge. |
bots.known_agents |
— | googlebot, bingbot, … | Daftar crawler dikenal. |
bots.unverified_claim_signal |
SHIELD_BOT_UNVERIFIED_CLAIM_SIGNAL |
4 |
Skor klaim crawler gagal verifikasi. |
bots.verification.enabled |
SHIELD_BOT_VERIFICATION_ENABLED |
true |
Nyalakan verifikasi identitas crawler. |
bots.verification.ttl_hours |
SHIELD_BOT_VERIFICATION_TTL_HOURS |
24 |
Cache hasil verifikasi per IP. |
bots.verification.hostnames |
— | googlebot → .googlebot.com, … |
Suffix PTR per agent. |
bots.verification.ip_ranges |
— | [] |
CIDR allowlist per agent (fallback tanpa DNS). |
Catatan: default
bots.modeberubah darichallengemenjadiobservepada1.2.0supaya crawler resmi tidak lagi diblokir saat verifikasi gagal. Config yang sudah di-publish tidak ikut berubah — lihat Upgrade ke v1.2.2.
Rule pack & inspeksi body
Section titled “Rule pack & inspeksi body”| Kunci | Env | Default | Keterangan |
|---|---|---|---|
rules.packs.wordpress |
SHIELD_RULES_PACK_WORDPRESS |
false |
Rule plugin WordPress. |
rules.packs.injection |
SHIELD_RULES_PACK_INJECTION |
true |
Rule SQLi/XSS/LFI/command-injection. |
rules.skip_paths |
— | [] |
Prefix path yang tidak dipindai body maupun dinilai perilakunya. Signature di URI tetap aktif. |
inspection.body.enabled |
SHIELD_INSPECTION_BODY_ENABLED |
true |
Periksa body POST/JSON untuk rule injection. |
inspection.body.max_bytes |
SHIELD_INSPECTION_BODY_MAX_BYTES |
65536 |
Batas body yang diperiksa (multipart di-skip; body tak pernah di-log). |
rules.skip_paths
Section titled “rules.skip_paths”Rule XSS/LFI bernilai 12, sedangkan ambang challenge bawaan 10, jadi payload JSON yang sah (rich text editor, webhook, data terenkripsi) bisa memicu challenge. Hal yang sama terjadi pada traffic M2M: penghitung perilaku di-key dengan IP, sehingga satu gerbang yang melayani banyak klien terlihat seperti brute force.
Masukkan prefix path yang memang tidak cocok dengan model tersebut:
'rules' => [ 'skip_paths' => [ '/oauth/token', '/api/webhooks', '/admin/reports/datatable', ],],Yang tidak berubah: signature di URI tetap dijalankan, jadi /.env atau
?file=../../etc/passwd di path yang sama tetap diblokir. Gunakan
allowlist hanya bila Anda benar-benar ingin melewati scoring juga.
Klien API / M2M
Section titled “Klien API / M2M”| Kunci | Env | Default | Keterangan |
|---|---|---|---|
api.paths |
— | [] |
Prefix path yang selalu dapat jawaban JSON, walau tanpa header Accept. |
api.detect_accept |
SHIELD_API_DETECT_ACCEPT |
true |
Deteksi otomatis Accept: application/json. |
Blok dan challenge otomatis memakai bentuk JSON bila request-nya menegosiasikan
JSON atau path-nya ada di api.paths. Bentuk jawabannya:
| Kasus | Status | Header | Body |
|---|---|---|---|
| Blokir | response_code (default 404) |
X-Shield-Blocked: <rule id> |
{ error, app_id, rule_id, decision, score } |
| Challenge | 401 |
X-Shield-Challenge: 1 |
{ error, app_id, challenge_url } |
Status blokir sengaja tetap mengikuti response_code supaya keberadaan
firewall tidak terkonfirmasi ke penyerang; hanya representasinya yang berubah.
Browser tetap menerima HTML dan redirect seperti sebelumnya.
Logging & privasi
Section titled “Logging & privasi”| Kunci | Env | Default | Keterangan |
|---|---|---|---|
logging.level |
SHIELD_LOG_LEVEL |
suspicious |
all, suspicious, atau blocked. |
logging.bypass_events |
SHIELD_LOG_BYPASS_EVENTS |
true |
Catat juga short circuit allowlist dan fail-closed. |
logging.retention_days |
SHIELD_LOG_RETENTION_DAYS |
30 |
Retensi event (default shield:prune --days). |
privacy.sensitive_query_parameters |
— | token, password, key, … |
Param query yang di-mask (***) saat disimpan. |
logging.level menggantikan boolean logging.events yang lama:
| Level | Yang disimpan |
|---|---|
suspicious |
Semua keputusan selain ALLOW: challenge, observe, blokir, ban. |
blocked |
Hanya blokir dan ban sementara. |
all |
Setiap request, termasuk yang diizinkan. |
Mulai v1.2.1 default bukan lagi “semua request”. Pada situs sibuk, mencatat
setiap request membuat tabel security_events tumbuh tanpa batas dan
menenggelimi baris yang justru Anda butuhkan. Kalau Anda memang requieren
all (mis. hanya untuk debugging singkat), setel ulang secara eksplisit:
SHIELD_LOG_LEVEL=allshield:prune kini dijadwalkan otomatis setiap hari, jadi Anda tidak perlu
mendaftarkan cron sendiri. Aplikasi Anda tetap wajib menjalankan
php artisan schedule:run setiap menit.
| Kunci | Env | Default | Keterangan |
|---|---|---|---|
admin.enabled |
SHIELD_ADMIN_ENABLED |
false |
Aktifkan surface admin. |
admin.middleware |
— | ['web','auth'] |
Middleware route admin. |
admin.authorize |
SHIELD_ADMIN_AUTHORIZE |
'' |
Nama Gate; semua aksi admin butuh can($gate). |
admin.prefix |
— | shield |
Prefix route admin. |
Performa & branding
Section titled “Performa & branding”| Kunci | Env | Default | Keterangan |
|---|---|---|---|
performance.max_uri_length |
SHIELD_MAX_URI_LENGTH |
2048 |
Batas panjang URI. |
performance.ban_cache_ttl_seconds |
SHIELD_BAN_CACHE_TTL |
30 |
TTL cache ban aktif. |
views.blocked / views.challenge |
SHIELD_VIEW_BLOCKED / SHIELD_VIEW_CHALLENGE |
shield::blocked / shield::challenge |
View kustom. |
branding.title |
SHIELD_BRANDING_TITLE |
Ganadev Laravel Shield |
Judul halaman. |
branding.accent_color |
SHIELD_BRANDING_ACCENT |
#22d3ee |
Warna aksen. |
branding.background_color |
SHIELD_BRANDING_BG |
#0b1220 |
Warna latar. |
branding.show_rule_id |
SHIELD_BRANDING_SHOW_RULE_ID |
false |
Tampilkan rule id di halaman blok. Default false sejak v1.2.1 karena membocorkan detail signature; nyalakan hanya di pengembangan. |
Allowlist & validasi
Section titled “Allowlist & validasi”allowlist.hosts/allowlist.paths/allowlist.ips— pengecualian; tidak pernah mengecualikan rule critical.- Konfigurasi divalidasi saat boot; nilai tidak dikenal akan memicu
InvalidConfigException.
Aturan allowlist.paths
Section titled “Aturan allowlist.paths”| Entri | Hasil |
|---|---|
'' atau '/' |
Ditolak. Pencocokan prefix akan membuat seluruh request ter-allowlist. |
Tanpa leading / |
Ditolak. Mis. 'admin' harus ditulis '/admin'. |
| Mengandung query string | Ditolak. Mis. '/admin?debug=1'. |
| Spasi di sekitar nilai | Di-trim otomatis. |
Untuk meng-allowlist satu host penuh, pakai allowlist.hosts atau allowlist.ips, bukan allowlist.paths.
Catatan: pencocokan berupa prefix, jadi
'/admin'juga mencakup'/administrator'.
api.paths dan rules.skip_paths mengikuti aturan validasi yang sama, kecuali
keduanya tolak nilai '/' dan string kosong, karena akan mengubah perilaku
seluruh request.
Perubahan validasi ini berasal dari 1.2.0 dan dapat membuat aplikasi gagal boot — lihat
Upgrade ke v1.2.2.
Powered by PT Ganadev Multi Solusi