Lewati ke konten

Laravel Shieldv1.2.x

Konfigurasi

Semua opsi Shield ada di satu file: config/shield.php. File itu muncul setelah Anda menjalankan vendor:publish --tag=shield-config.

Setiap kunci punya dua cara diatur:

  1. Langsung di config/shield.php — untuk nilai yang spesifik untuk aplikasi Anda.
  2. Lewat environment variable — untuk nilai yang berbeda tiap server (staging dan produksi, misalnya). Ini yang kami rekomendasikan.

mode menentukan seberapa keras Shield bertindak:

Mode Yang terjadi pada request mencurigakan
observe Dicatat sebagai kejadian. Tidak ada yang diblokir dan tidak ada challenge.
challenge Ban diturunkan menjadi challenge — pengunjung diminta membuktikan bahwa dia manusia.
enforce Diblokir sepenuhnya, dan IP-nya diban.

Selalu mulai dari observe. Naikkan ke mode yang lebih ketat setelah Anda memastikan tidak ada yang salah sasaran.

  • Rule (denylist) = pola yang harus diblokir. Shield sudah punya banyak, dan Anda bisa menambah atau menyesuaikan sendiri.
  • Allowlist = daftar yang dikecualikan dari pemeriksaan. Gunakan hemat.

Shield tidak memakai satu aturan “tolak atau tidak”. Setiap sinyal menambah skor, lalu skor itu dibandingkan dengan ambang batas:

Kunci Env Default Arti
thresholds.challenge SHIELD_THRESHOLD_CHALLENGE 10 Skor mulai menimbulkan challenge.
thresholds.ban SHIELD_THRESHOLD_BAN 20 Skor mulai menimbulkan ban sementara.
thresholds.strong_ban SHIELD_THRESHOLD_STRONG_BAN 30 Skor menimbulkan ban dengan durasi terpanjang.

Ketiganya wajib naik berurutan. Nilai yang sama atau turun akan ditolak saat boot dengan InvalidConfigException, karena membuat keputusan jadi tidak dapat diprediksi. Menurunkan challenge berarti lebih sedikit challenge terbit; menaikkan ban membuat ban lebih jarang tapi lebih lambat.

Jadi beberapa sinyal lemah yang kemunculan bersama bisa menjatuhkan, sementara satu sinyal lemah saja belum cukup untuk memblokir.

Kunci Env Default Keterangan
enabled SHIELD_ENABLED true Master switch. false mematikan Shield sepenuhnya.
mode SHIELD_MODE observe observe | challenge | enforce.
app_id SHIELD_APP_ID my-app Namespace cache. Wajib diubah kalau dua aplikasi berbagi cache.
response_code SHIELD_RESPONSE_CODE 404 Kode HTTP saat memblokir. 404 menyembunyikan keberadaan firewall.
decode_depth — 2 Berapa kali URL di-decode (0–3). Naikkan hanya kalau ada aturan tak terdeteksi.
fail_mode SHIELD_FAIL_MODE open open atau closed saat database/cache mati. Lihat catatan di bawah.
rule_version — 1.0.0 Versi aturan, dicatat di setiap kejadian.

Kalau database atau cache sedang tidak bisa dijangkau, Shield harus memutuskan satu hal: biarkan request lewat, atau blokir semuanya?

Nilai Perilaku Kapan dipakai
open Request normal tetap lewat. Aturan kritis tetap diblokir karena tidak butuh database. Hampir selalu benar.
closed Semua request diblokir sampai infrastruktur pulih. Hanya kalau Anda lebih siap menerima downtime daripada risiko gagal.
Kunci Default Keterangan
ban.durations [15, 60, 360, 1440] Durasi ban dalam menit, untuk offense ke-1, 2, 3, dan 4.
escalation.step 5 Skor tambahan per offense (maksimal 5 offense yang dihitung).

Artinya ban.durations di atas berarti:

Offense Durasi ban
1 15 menit
2 1 jam
3 6 jam
4 24 jam
5 ke atas 24 jam + flag manual_review
Kunci Env Default Keterangan
challenge.driver SHIELD_CHALLENGE turnstile turnstile | recaptcha | null.
challenge.turnstile.site_key SHIELD_TURNSTILE_SITE_KEY '' Kunci publik untuk widget.
challenge.turnstile.secret_key SHIELD_TURNSTILE_SECRET_KEY '' Kunci rahasia untuk verifikasi server.
challenge.recaptcha.site_key SHIELD_RECAPTCHA_SITE_KEY '' Sama, untuk reCAPTCHA.
challenge.recaptcha.secret_key SHIELD_RECAPTCHA_SECRET_KEY '' Sama, untuk reCAPTCHA.
challenge.turnstile.verify_url SHIELD_TURNSTILE_VERIFY_URL endpoint Cloudflare Alamat server verifikasi.
challenge.recaptcha.verify_url SHIELD_RECAPTCHA_VERIFY_URL endpoint Google Alamat server verifikasi.

null berarti challenge dilewati begitu saja tanpa memanggil pihak ketiga. Berguna untuk development dan test otomatis — jangan dipakai di produksi.

Secret tidak pernah disimpan ke database maupun ditulis ke log.

Sinyal di sini menangkap bot yang menghindari pola statis: yang memakai URL sah, tetapi dengan volume yang tidak wajar.

Kunci Env Default Keterangan
behavior.unique_uri_limit SHIELD_BEHAVIOR_UNIQUE_URI_LIMIT 25 Batas URI berbeda dalam satu jendela waktu.
behavior.window_seconds SHIELD_BEHAVIOR_WINDOW_SECONDS 60 Panjang jendela waktu, dalam detik.
behavior.not_found_limit SHIELD_BEHAVIOR_NOT_FOUND_LIMIT 20 Batas respons 404 dalam satu jendela.
behavior.missing_referer_signal SHIELD_BEHAVIOR_MISSING_REFERER true Sinyal lemah (+2) untuk POST tanpa header Referer.
behavior.scanner_user_agents — 13 nama alat User-Agent alat scanner keamanan.
behavior.scanner_ua_signal SHIELD_BEHAVIOR_SCANNER_UA_SIGNAL 4 Skor untuk User-Agent scanner.
behavior.suspicious_user_agents — [] Tambahan penanda klien yang ingin Anda awasi.
behavior.path_rate_limit SHIELD_BEHAVIOR_PATH_RATE_LIMIT 30 Batas request per path biasa dalam jendela.
behavior.sensitive_path_rate_limit SHIELD_BEHAVIOR_SENSITIVE_PATH_RATE_LIMIT 8 Batas lebih ketat untuk endpoint login.
behavior.sensitive_paths — 7 path bawaan Path yang memakai batas ketat.

Counter perilaku disimpan di cache dengan key yang di-namespace oleh app_id, jadi dua aplikasi yang berbagi Redis tidak saling menimpa.

Tambahkan path login Anda sendiri kalau tidak ada di daftar bawaan:

'behavior' => [
'sensitive_paths' => [
'/login',
'/admin/login',
'/api/login',
'/masuk', // path lokal aplikasi Anda
'/auth/token', // endpoint API Anda
],
],
Kunci Env Default Keterangan
bots.mode SHIELD_BOT_MODE observe off | observe | challenge.
bots.known_agents — googlebot, bingbot, … Daftar crawler yang dikenali.
bots.verification.enabled SHIELD_BOT_VERIFICATION_ENABLED true Cek IP asli crawler sebelum dipercaya.
bots.verification.ttl_hours SHIELD_BOT_VERIFICATION_TTL_HOURS 24 Lama hasil verifikasi disimpan.
bots.verification.hostnames — .googlebot.com, … Suffix hostname yang sah untuk tiap crawler.
bots.verification.ip_ranges — [] CIDR resmi crawler. Lihat catatan di bawah.
bots.unverified_claim_signal SHIELD_BOT_UNVERIFIED_CLAIM_SIGNAL 4 Skor untuk klaim crawler yang gagal diverifikasi.
Kunci Env Default Keterangan
rules.packs.wordpress SHIELD_RULES_PACK_WORDPRESS false Rule khusus plugin WordPress.
rules.packs.injection SHIELD_RULES_PACK_INJECTION true Rule SQLi, XSS, LFI, dan command injection.
rules.skip_paths — [] Prefix path yang dikecualikan dari inspeksi body dan sinyal perilaku.
inspection.body.enabled SHIELD_INSPECTION_BODY_ENABLED true Periksa juga isi body request.
inspection.body.max_bytes SHIELD_INSPECTION_BODY_MAX_BYTES 65536 Batas body yang dibaca (64 KB).

Beberapa endpoint wajar mengirim pola yang dianggap berbahaya:

  • endpoint webhook yang menerima JSON berisi kode atau markup,
  • rich text editor yang menyimpan HTML mentah,
  • gerbang API yang melayani banyak klien dari satu IP (M2M).

Rule XSS bernilai 12, sedangkan ambang challenge bawaannya 10 — jadi payload JSON yang sah bisa memicu challenge. Untuk endpoint seperti itu, daftarkan path-nya:

'rules' => [
'skip_paths' => [
'/oauth/token',
'/api/webhooks',
'/admin/reports/datatable',
],
],

Yang tidak berubah: signature di URI tetap dijalankan. /.env atau ?file=../../etc/passwd di path yang sama tetap diblokir.

Kunci Env Default Keterangan
api.paths — [] Prefix path yang selalu dibalas JSON.
api.detect_accept SHIELD_API_DETECT_ACCEPT true Deteksi otomatis dari header Accept.

Tanpa ini, aplikasi API Anda bisa menerima halaman HTML saat Shield memblokir sebuah request — dan klien API Anda akan gagal dengan pesan yang membingungkan.

Kasus Status Header Bentuk 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. Yang berubah hanya bentuk responsnya.

Kunci Env Default Keterangan
logging.level SHIELD_LOG_LEVEL suspicious all | suspicious | blocked.
logging.bypass_events SHIELD_LOG_BYPASS_EVENTS true Catat juga allowlist dan fail-closed.
logging.retention_days SHIELD_LOG_RETENTION_DAYS 30 Umur data sebelum dibersihkan.
privacy.sensitive_query_parameters — token, password, passwd, key, secret, code, auth Disamarkan jadi *** sebelum disimpan.

Pencocokan nama parameter bersifat case-insensitive dan sudah menangani kunci yang di-percent-encode, sehingga access%5Ftoken ikut disamarkan. Tambahkan nama parameter khusus aplikasi Anda di sini. Parameter yang tidak terdaftar akan tersimpan apa adanya, jadi pastikan tidak ada yang lupa.

Apa arti masing-masing level:

Level Yang disimpan
suspicious Semua keputusan selain “Izinkan”: challenge, amati, blokir, dan ban.
blocked Hanya blokir dan ban.
all Setiap request, termasuk yang diizinkan.

shield:prune sudah dijadwalkan otomatis setiap hari oleh Shield. Aplikasi Anda tetap wajib menjalankan php artisan schedule:run setiap menit.

Kunci Env Default Keterangan
admin.enabled SHIELD_ADMIN_ENABLED false Nyalakan Admin API.
admin.middleware — ['web','auth'] Middleware untuk route admin.
admin.authorize SHIELD_ADMIN_AUTHORIZE '' Nama Gate yang wajib dimiliki.
admin.prefix — shield Prefix URL route admin.

admin.enabled tidak aktif secara default dan sebaiknya tetap begitu. Kalau Anda menyalakannya, isi juga admin.authorize — kalau tidak, setiap pengguna yang sekadar login bisa mengelola ban. Detailnya ada di Admin API.

Kunci Env Default Keterangan
performance.max_uri_length SHIELD_MAX_URI_LENGTH 2048 Batas panjang URL.
performance.ban_cache_ttl_seconds SHIELD_BAN_CACHE_TTL 30 Lama ban aktif disimpan di cache.
views.blocked SHIELD_VIEW_BLOCKED shield::blocked Tampilan halaman blokir.
views.challenge SHIELD_VIEW_CHALLENGE shield::challenge Tampilan halaman challenge.
branding.title SHIELD_BRANDING_TITLE Ganadev Laravel Shield Judul di halaman blokir dan challenge.
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 blokir.
Kunci Env Default Keterangan
trusted.enabled — true Ingat pengunjung yang sudah lolos challenge.
trusted.ttl_minutes SHIELD_TRUSTED_TTL_MINUTES 60 Lama cookie trusted berlaku.

Cookie trusted terikat pada IP, User-Agent, dan prefix jaringan asal, jadi tidak bisa dipinjam dari komputer atau IP lain. Trusted cookie hanya melewati keputusan challenge; ban aktif dan signature critical tetap ditegakkan.

Nilai moderat seperti 30 sampai 120 menit biasanya cukup. Makin panjang, makin lama cookie itu tetap berlaku di browser yang tertinggal di komputer bersama.

'allowlist' => [
'hosts' => [],
'paths' => [],
'ips' => [],
],

Daftar ini mengecualikan request dari pemrosesan. Tetap ingat: tidak pernah mengecualikan aturan kritis.

Entri Hasil
'' atau '/' Ditolak. Pencocokan prefix akan mengecualikan seluruh request.
Tanpa / di depan Ditolak. 'admin' harus ditulis '/admin'.
Mengandung query string Ditolak. Contohnya '/admin?debug=1'.
Ada spasi di sekitar Otomatis di-trim.

Untuk mengecualikan satu host penuh, pakai allowlist.hosts atau allowlist.ips, bukan allowlist.paths.

Validasi ini dijalankan saat aplikasi boot. Nilai yang salah akan membuat aplikasi gagal start dengan pesan InvalidConfigException — lebih baik gagal dini daripada berjalan dengan allowlist yang keliru.

api.paths dan rules.skip_paths mengikuti aturan yang sama, kecuali keduanya menolak nilai '/' dan string kosong.

SHIELD_ENABLED=true
SHIELD_MODE=challenge
SHIELD_APP_ID=toko-online
SHIELD_CHALLENGE=turnstile
SHIELD_TURNSTILE_SITE_KEY=0x4AAAAAAA...
SHIELD_TURNSTILE_SECRET_KEY=0x4AAAAAAA...
SHIELD_BOT_MODE=observe
SHIELD_LOG_LEVEL=suspicious
SHIELD_LOG_RETENTION_DAYS=14
SHIELD_ADMIN_ENABLED=false
SHIELD_BRANDING_SHOW_RULE_ID=false

Naikkan SHIELD_MODE ke enforce setelah beberapa hari mode challenge berjalan tanpa false positive yang berarti.

Powered by PT Ganadev Multi Solusi