Laravel Shieldv1.2.x
Rules
Rule adalah pola yang harus dicek di setiap request. Shield mencocokkan request Anda dengan seluruh rule yang aktif, lalu menjumlahkan skor dari rule yang cocok.
Rule bawaan
Section titled “Rule bawaan”Shield datang dengan tiga paket rule:
| Paket | Jumlah rule | Status default |
|---|---|---|
| Dasar (probe, file sensitif, traversal, RCE, credential, honeypot) | 37 | Aktif |
| Injection (SQLi, XSS, LFI, command injection) | 14 | Aktif |
| WordPress (probe CMS dan plugin) | 6 | Nonaktif |
Jadi sejak awal ada 51 rule aktif. Paket WordPress sengaja nonaktif karena hanya relevan kalau aplikasi Anda memang WordPress.
'rules' => [ 'packs' => [ 'wordpress' => false, // nyalakan hanya kalau situs Anda memang WordPress 'injection' => true, // biarkan aktif kecuali ada alasan kuat ],],Struktur satu rule
Section titled “Struktur satu rule”Setiap rule punya bentuk yang sama:
[ 'id' => 'sensitive.env', // pengenal unik 'category' => 'sensitive_file', // pengelompokan 'matcher' => 'contains', 'value' => '/.env', 'severity' => 'critical', // low | medium | high | critical 'score' => 30, // bobot skor 'immediate_ban' => true, 'enabled' => true,],Kunci yang tersedia
Section titled “Kunci yang tersedia”| Kunci | Wajib | Keterangan |
|---|---|---|
id |
Ya | Pengenal unik. String kosong akan membuat error saat boot. |
matcher |
Ya | Cara pencocokan (lihat tabel di bawah). |
value |
Ya | String yang dicari. Boleh kosong, kecuali untuk regex. |
severity |
Tidak | Ditentukan otomatis dari score kalau tidak diisi. |
score |
Tidak | Ditentukan otomatis dari severity kalau tidak diisi. |
category |
Tidak | Default general. |
immediate_ban |
Tidak | Default false. |
enabled |
Tidak | Default true. |
Hubungan severity dan score
Section titled “Hubungan severity dan score”Kalau score tidak ditulis, nilainya diambil dari severity:
severity |
Skor default |
|---|---|
low |
4 |
medium |
12 |
high |
20 |
critical |
30 |
Sebaliknya, kalau severity tidak ditulis, critical ditentukan dari skor 30
ke atas. Menulis keduanya secara eksplisit lebih aman daripada mengandalkan
tebakan ini.
Jenis pencocokan (matcher)
Section titled “Jenis pencocokan (matcher)”matcher |
Cocok kalau |
|---|---|
exact |
Nilainya persis sama. |
prefix |
URL diawali nilai tersebut. |
contains |
Nilai tersebut muncul di URL. |
regex |
Ekspresi reguler cocok. |
query_contains |
Nilai tersebut muncul di query string. |
decoded_contains |
Cocok setelah URL di-decode berulang kali. |
body_contains |
Nilai tersebut muncul di body request. |
body_regex |
Ekspresi reguler cocok di body request. |
Pilih decoded_contains untuk hampir semua rule probe, bukan contains:
penyerang biasa menyembunyikan payload-nya di balik URL encoding berulang
(%252e%252e%252f). Kalau aturan Anda memakai contains saja, teknik itu
melewatkannya.
Menyesuaikan rule bawaan
Section titled “Menyesuaikan rule bawaan”Cukup tulis id yang sama. Field yang Anda tulis akan menimpa field bawaan; yang
tidak Anda tulis tetap memakai nilai asli.
Contoh: naikkan /.env jadi ban seketika.
'rules' => [ 'packs' => ['injection' => true],
// id yang sama berarti menimpa, bukan membuat duplikat [ 'id' => 'sensitive.env', 'severity' => 'critical', 'score' => 35, 'immediate_ban' => true, ],],Contoh: kurangi bobot rule yang terlalu sering menimpa konten sah di aplikasi Anda.
[ 'id' => 'payload.xss.script', 'severity' => 'low', 'score' => 4,],Contoh: matikan satu rule tanpa menghapus definisinya.
[ 'id' => 'sensitive.env', 'enabled' => false,],Menambah rule sendiri
Section titled “Menambah rule sendiri”Kalau id tidak ditemukan di rule bawaan, definisi Anda ditambahkan sebagai
rule baru. Tidak perlu mendaftarkan file terpisah.
Contoh 1: daftar endpoint yang tidak boleh diakses
Section titled “Contoh 1: daftar endpoint yang tidak boleh diakses”'rules' => [ // Service internal hanya boleh dipanggil lewat API, bukan peramban [ 'id' => 'internal_service', 'matcher' => 'prefix', 'value' => '/internal/', 'severity' => 'high', 'score' => 25, 'immediate_ban' => true, ],],Contoh 2: melarang nama file tertentu
Section titled “Contoh 2: melarang nama file tertentu”[ 'id' => 'forbidden_dump', 'matcher' => 'decoded_contains', 'value' => '.sql', 'severity' => 'high', 'score' => 20,],Contoh 3: pola di body request
Section titled “Contoh 3: pola di body request”Berguna untuk endpoint yang menerima JSON atau form.
[ 'id' => 'body_script_tag', 'matcher' => 'body_contains', 'value' => '<script', 'severity' => 'medium', 'score' => 12,],Contoh 4: ekspresi reguler
Section titled “Contoh 4: ekspresi reguler”[ 'id' => 'email_header_injection', 'matcher' => 'regex', 'value' => '[\r\n](bcc|cc)\s*:', 'severity' => 'medium', 'score' => 12,],Shield menjalankan pemeriksaan keamanan pada regex yang Anda tulis: pola diuji
terhadap payload 64 karakter berulang ditambah tanda seru, dan kalau eksekusinya
melewati 50 milidetik, aplikasi gagal boot dengan pesan
Regex rule may be ReDoS-prone.
Jadi pola seperti (a+)+$ akan ditolak saat boot — bukan saat produksi melambat.
Tetap saja, tulislah regex sesempit mungkin.
Melihat daftar lengkap rule bawaan
Section titled “Melihat daftar lengkap rule bawaan”Bisa dibaca langsung di source:
vendor/ganadev/shield-core/src/Rules/DefaultRules.phpUntuk melihat rule yang benar-benar aktif di aplikasi Anda:
php artisan shield:rules:listRingkasan
Section titled “Ringkasan”| Situasi | Yang harus dilakukan |
|---|---|
| Aplikasi normal, tidak ada masalah | Biarkan default: 51 rule aktif dengan mode: observe. |
| Ada false positive yang mengganggu | Turunkan score rule terkait, atau set enabled: false. |
| Ingin nilai tambah khusus aplikasi | Tambah rule baru di config/shield.php. |
| Ada endpoint yang wajar mengirim payload | Pakai rules.skip_paths, jangan mematikan rule-nya. |
| Ingin aturan yang benar-benar kritis | Naikkan severity ke critical dan immediate_ban: true. |
Kalau Anda ragu apakah sebuah pola perlu diblokir, pakai mode: observe lebih
dulu dan periksa log. Datanya akan memberi tahu apakah kekhawatiran Anda
tentang false positive memang terjadi.
Powered by PT Ganadev Multi Solusi