Lewati ke konten

Upgrade ke v1.2.2

Panduan ini untuk aplikasi yang sudah memakai 1.0.x dan ingin naik ke 1.2.2. Tidak ada breaking change pada API publik di rilis ini.

Versi shield-core laravel-shield Isi
1.0.0 Core Adapter Rilis awal.
1.0.1 Patch aditif Patch aditif Exemption route admin, race condition counter cache, admin_authorize_warning.
1.2.0 Default bots.mode, validasi allowlist.paths + TrustedProxyInspector, warning boot, perbaikan shield:health Default crawler dan validasi allowlist.
1.2.1 logging.level, rules.skip_paths, metadata API/M2M + jawaban JSON untuk API, auto-schedule prune, guard observe, probe DNS, default show_rule_id Ditarik dari Packagist, lihat catatan di bawah.
1.2.2 Rilis packaging, kode identik dengan 1.2.1 Rilis packaging, kode identik dengan 1.2.1 Rilis ini.
Terminal window
composer require ganadev/laravel-shield:^1.2.2 ganadev/shield-core:^1.2.2

Untuk aplikasi yang sudah terpasang:

Terminal window
composer update ganadev/laravel-shield ganadev/shield-core

laravel-shield meng-require ganadev/shield-core: ^1.2.1 karena adapter memakai API config baru dari core (skip_paths, api.paths, logging.level). Compose akan menarik core yang cocok secara otomatis, jadi tidak ada constraint yang perlu Anda ubah sendiri.

Seksi 1–4 sudah terbit di v1.2.0 dan tetap relevan kalau Anda naik langsung dari 1.0.x. Seksi 5–11 adalah perubahan baru yang tertampung di rilis v1.2.2.

1. Default bots.mode berubah dari challenge menjadi observe (v1.2.0)

Section titled “1. Default bots.mode berubah dari challenge menjadi observe (v1.2.0)”

Sebelumnya bots.mode bernilai challenge. Begitu reverse-DNS atau CIDR gagal — DNS bermasalah, resolver diblokir, atau domain crawler belum terdaftar — crawler resmi diklaim palsu lalu mendapat challenge, padahal /robots.txt dan /sitemap.xml harus selalu bisa diakses. Sekarang crawler tak terverifikasi dilayani dan hanya dicatat (unverified_crawler_claim tetap masuk skor), bukan di-challenge.

Mode challenge tetap tersedia sebagai opsi eksplisit bila Anda memang membutuhkannya.

2. Validasi allowlist.paths saat boot (v1.2.0)

Section titled “2. Validasi allowlist.paths saat boot (v1.2.0)”

Nilai allowlist.paths kini diperiksa ketika konfigurasi dimuat. Entri yang ditolak:

Nilai Alasan
'' atau '/' Pencocokan memakai str_starts_with(), jadi keduanya membuat seluruh request ter-allowlist.
Tanpa leading / Mis. 'admin' — tidak valid sebagai prefix path.
Mengandung query string Mis. '/admin?debug=1'.

Semua entri juga di-trim, sehingga spasi di sekitar nilai tidak lagi mengubah apa yang ter-allowlist.

Pesan exception yang akan muncul:

allowlist.paths must be specific path prefixes starting with "/".
The value "/" would allowlist every request.
To allowlist a whole host use allowlist.hosts or allowlist.ips instead.

Untuk meng-allowlist satu host penuh, pakai allowlist.hosts atau allowlist.ips — keduanya tidak punya batasan ini dan sudah tersedia sejak 1.0.0.

Rule critical tetap tidak bisa di-bypass oleh allowlist mana pun: guard hasCriticalMatch juga berlaku untuk entri allowlist path.

3. Deteksi trusted proxy saat boot (v1.2.0)

Section titled “3. Deteksi trusted proxy saat boot (v1.2.0)”

TrustedProxyInspector membaca konfigurasi proxy dari static TrustProxies, karena Request::getTrustedProxies() hanya mencerminkan request berjalan sehingga selalu kosong dari CLI.

Dua efek:

  • Warning saat boot. Kalau trusted proxies belum dikonfigurasi, mode challenge/enforce, dan app.url menunjuk host publik, aplikasi mencatat Ganadev Shield: trusted proxies belum dikonfigurasi... ke log. Sebelumnya masalah ini baru terlihat kalau somebody menjalankan shield:health.
  • shield:health tidak lagi false negative. Tabel health sebelumnya keluar sebelum membaca konfigurasi, sehingga kondisi berbahaya (header forwarded terdeteksi tapi trusted proxies kosong) tidak pernah diberi warning.

4. config/shield.php sekarang terdokumentasi inline (v1.2.0)

Section titled “4. config/shield.php sekarang terdokumentasi inline (v1.2.0)”

Setiap kelompok kunci pada config/shield.php bawaan punya banner komentar yang menjelaskan konsekuensi tiap default, bukan hanya nama kuncinya. Ini penting untuk hal-hal yang mudah salah set, misalnya:

  • bots.verification.enabled dimatikan justru membuat semua crawler dianggap palsu, bukan dianggap sah.
  • /admin pada allowlist.paths juga mencakup /administrator, karena pencocokan berupa prefix.
  • ban.durations dalam menit, dan nilai offense meluruh satu per 24 jam tanpa request.
  • escalation.step tidak berlaku pada request pertama dari sebuah IP, karena jumlah offense diambil dari ban yang masih aktif.

Untuk membaca versi terbaru tanpa meng-overwrite konfigurasi Anda:

Terminal window
php artisan vendor:publish --tag=shield-config --force # menimpa konfigurasi Anda

Sebaiknya baca langsung dari vendor/ganadev/laravel-shield/config/shield.php.

5. logging.events (boolean) diganti logging.level (v1.2.1)

Section titled “5. logging.events (boolean) diganti logging.level (v1.2.1)”

Recorder sebelumnya menulis setiap request ke security_events. Pada situs sibuk itu membuat tabel tumbuh tanpa batas dan menenggelimi baris yang justru Anda butuhkan untuk menyetel ambang batas.

'logging' => [
'events' => true,
'level' => 'suspicious', // all | suspicious | blocked
'bypass_events' => true,
'retention_days' => 30,
],
Level Yang disimpan
suspicious (default) Semua keputusan selain ALLOW.
blocked Hanya blokir dan ban sementara.
all Setiap request, termasuk yang diizinkan. Setel ini hanya untuk debugging singkat.

ShieldConfig::$logEvents (bool) diganti menjadi ShieldConfig::$loggingLevel (string), dengan konstanta ShieldConfig::LOG_ALL, LOG_SUSPICIOUS, dan LOG_BLOCKED. Nilai di luar tiga itu itu ditolak saat boot.

Konfigurasi yang sudah di-publish tidak ikut berubah: file Anda masih berisi 'events' => true, yang sekarang diabaikan, dan level memakai default suspicious. Kalau Anda memang ingin mencatat semua request, tambahkan 'level' => 'all' secara eksplisit.

logging.bypass_events kini akhirnya bisa diatur dari config Laravel; sebelumnya hanya ada sebagai default di core dan tidak pernah diekspos.

Service provider mendaftarkan shield:prune harian. Anda tidak perlu mendaftarkan cron sendiri, tetapi aplikasi tetap wajib menjalankan php artisan schedule:run setiap menit. Kalau Anda sudah punya entri Schedule::command('shield:prune') sendiri, hapus agar tidak berjalan dua kali.

7. branding.show_rule_id default true menjadi false

Section titled “7. branding.show_rule_id default true menjadi false”

Halaman blokir tidak lagi menampilkan ID rule ke penyerang. Header X-Shield-Blocked tetap mengirim rule id karena itu sinyal operator, bukan tangkapan layar.

Nyalakan kembali hanya di pengembangan:

SHIELD_BRANDING_SHOW_RULE_ID=true

Untuk kebutuhan debugging produksi, baca kolom rule_id dari tabel security_events.

Blok dan challenge otomatis memakai bentuk JSON bila request-nya menegosiasikan JSON atau path-nya ada di api.paths. Rinciannya ada di konfigurasi. Perubahan ini aditif: browser tetap menerima HTML dan redirect seperti sebelumnya, dan status blokir tetap mengikuti response_code.

9. rules.skip_paths untuk mengurangi false positive

Section titled “9. rules.skip_paths untuk mengurangi false positive”

Rule XSS/LFI bernilai 12 sedangkan ambang challenge bawaan 10, jadi teks bebas pada body (rich text editor, webhook, payload terenkripsi) bisa memicu challenge. Traffic M2M juga sering salah skor karena penghitung perilaku di-key dengan IP.

rules.skip_paths mematikan pemindaian body dan penilaian perilaku pada prefix yang Anda daftarkan. Signature di URI tetap aktif. Detail dan contoh di konfigurasi.

10. bots.mode=observe tidak lagi bisa di-eskalasi oleh perilaku

Section titled “10. bots.mode=observe tidak lagi bisa di-eskalasi oleh perilaku”

Klaim crawler yang gagal diverifikasi tidak lagi bisa menaikkan verdict ke challenge atau ban hanya karena sinyal perilaku, selama bots.mode=observe. Signature yang cocok dan ban aktif tetap ditegakkan. Rincian di docs bot.

  • safeRedirect() tidak lagi merusak query string. e() mengubah & menjadi &, yang mendarat apa adanya di header Location. Redirect dengan lebih dari satu parameter kini benar.
  • shield:health memeriksa resolusi DNS crawler. Baris baru Crawler verification melakukan probe PTR sekali jalan. Probe tidak pernah mengubah exit code.
  • Deteksi posisi middleware. LaravelTrustedCookie memberi peringatan satu kali bila cookie trusted diterima dalam bentuk sudah ter-decrypt, yang menandakan middleware dipindahkan ke group web.
  • Halaman blokir menyertakan Content-Type: text/html. Sebelumnya header itu tidak pernah di-set.
  1. Naikkan core dan adapter dalam satu perintah. Ini wajib, bukan opsional:

    Terminal window
    composer update ganadev/laravel-shield ganadev/shield-core

    laravel-shield:1.2.1 membutuhkan shield-core:1.2.1. Kalau core tertinggal di 1.2.0, middleware gagal saat runtime karena properti skip_paths/api.paths belum ada. Verifikasi setelahnya:

    Terminal window
    composer show ganadev/shield-core ganadev/laravel-shield
  2. Cek allowlist.paths — sumber paling mungkin menggagalkan boot.

    Terminal window
    php artisan tinker --execute="dump(config('shield.allowlist.paths'));"

    Kosongkan dulu ('paths' => []) kalau ada '', '/', entri tanpa / awal, atau entri ber-query-string.

  3. Catat mode crawler yang aktif supaya bisa dibandingkan nanti.

    Terminal window
    php artisan tinker --execute="dump(config('shield.bots.mode'));"
  4. Pastikan tidak ada SHIELD_BOT_MODE di .env yang tak sengaja menahan perilaku lama, atau sebaliknya menyalakan perilaku yang tidak diinginkan.

  5. Backup config/shield.php bila sudah publish.

  6. Pastikan cron scheduler Laravel berjalan. shield:prune kini dijadwalkan otomatis oleh provider, tetapi tidak akan pernah jalan tanpa php artisan schedule:run.

    * * * * * cd /path/ke/aplikasi && php artisan schedule:run >> /dev/null 2>&1
  7. Periksa logging.level. Kalau Anda mengandalkan pencatatan setiap request, tambahkan 'level' => 'all'.

  1. Jalankan php artisan shield:health — pastikan tidak ada warning baru soal trusted proxy, dan periksa baris Crawler verification.

  2. Cek log boot untuk pesan trusted proxies belum dikonfigurasi. Kalau muncul dan Anda memang di belakang proxy, konfigurasi TrustProxies::at() lebih dulu.

  3. Verifikasi perilaku crawler:

    Terminal window
    php artisan tinker --execute="dump(config('shield.bots.mode'));"

    Kalau hasilnya masih challenge padahal Anda tidak menyetelnya, berarti config Anda belum di-publish ulang — lihat bagian 1.

  4. Jalankan php artisan shield:report dan bandingkan jumlah event sebelum/sesudah upgrade. penurunan jumlah event itu diharapkan, karena logging.level default suspicious tidak lagi mencatat request yang diizinkan.

  5. Kalau memakai mode challenge/enforce di produksi, lakukan dulu di staging.

  6. Kalau memakai M2M, webhook, atau rich text editor, daftarkan path-nya di rules.skip_paths lalu uji ulang.

Gejala Penyebab Solusi
Error: Undefined property pada skipPaths / apiPaths / loggingLevel shield-core masih di 1.2.0 atau lebih rendah Naikkan kedua package sekaligus: composer update ganadev/laravel-shield ganadev/shield-core.
Aplikasi gagal boot: allowlist.paths must be specific path prefixes... Entri '' atau '/' Bersihkan allowlist.paths, lihat bagian 2.
Aplikasi gagal boot: allowlist.paths entries must start with "/" Entri tanpa leading / Tambahkan / di depan, mis. 'admin' → '/admin'.
Aplikasi gagal boot: Invalid logging.level Nilai level tidak dikenal Gunakan all, suspicious, atau blocked.
Jumlah event turun drastis setelah upgrade logging.level default suspicious Ini disengaja, lihat bagian 5. Setel 'level' => 'all' bila memang perlu.
Tabel security_events tetap membesar Cron schedule:run tidak jalan Daftarkan cron scheduler, lihat bagian 6.
Klien API menerima HTML atau ikut di-redirect Klien tidak mengirim Accept: application/json Tambahkan path-nya ke api.paths, lihat bagian 8.
Rich text editor atau webhook ter-challenge Rule XSS/LFI bernilai 12 > ambang 10 Tambahkan path-nya ke rules.skip_paths, lihat bagian 9.
Klien di balik NAT/M2M ter-challenge padahal sah Penghitung perilaku di-key dengan IP Pakai rules.skip_paths untuk endpoint non-human-facing.
Muncul warning trusted proxies belum dikonfigurasi di log Trusted proxy belum dikonfigurasi padahal aplikasi berada di host publik Setel TrustProxies::at() atau abaikan bila memang tidak di belakang proxy.
Tiba-tiba tidak ada challenge pada crawler Konsekuensi yang disengaja dari default baru Setel SHIELD_BOT_MODE=challenge bila memang diinginkan.
Warning cookie trusted diterima dalam bentuk yang sudah ter-decrypt Middleware dipindahkan ke group web Kembalikan ke posisi global, lihat bagian 11.
shield:health melaporkan resolver tidak mengembalikan PTR Resolver tidak bisa menjawab reverse-DNS Periksa firewall keluar/DNS. Untuk crawler, isi bots.verification.ip_ranges sebagai fallback tanpa DNS.

Rilis 1.2.1 menutup sepuluh temuan dari audit internal dan laporan lapangan:

  • Klien API dan M2M yang menerima HTML atau redirect sehingga salah membaca sebagai error protokol.
  • safeRedirect() yang mengubah & menjadi & di header Location.
  • Pencatatan event untuk setiap request yang membuat tabel tumbuh tanpa batas.
  • Tidak adanya penjadwalan shield:prune secara default.
  • False positive rule XSS/LFI pada teks bebas, dan false positive perilaku pada traffic M2M/NAT.
  • bots.mode=observe yang tetap bisa di-challenge lewat skor perilaku sehingga crawler hilang dari indeks.
  • branding.show_rule_id yang membocorkan detail signature ke penyerang secara default.
  • shield:health yang belum menguji prasyarat DNS untuk verifikasi crawler.
  • Posisi middleware terhadap EncryptCookies yang tidak terdokumentasi dan gagal diam-diam saat bergeser.
  • Normalisasi prefix path yang membuat konfigurasi skip_paths/api.paths tidak pernah cocok.

Empat temuan sebelumnya sudah ditutup di 1.2.0: default bots.mode yang merusak SEO saat verifikasi crawler gagal, allowlist yang bisa dimatikan total tanpa warning, false negative shield:health soal trusted proxy, dan peringatan proxy yang dulu baru terlihat lewat perintah manual.

Yang belum ada di rilis ini: ekspresi kompleks untuk M2M, exemption berbasis identitas klien, dan pembedaan status verifikasi crawler unverified vs unavailable pada saat resolver sedang bermasalah.

Rujukan konfigurasi lengkap tetap di Konfigurasi.

Powered by PT Ganadev Multi Solusi