Lewati ke konten

CodeIgniter 4 Shieldv1.2.x

Konfigurasi

Mode Perilaku
observe Semua keputusan dicatat sebagai OBSERVE; tidak ada challenge atau blokir. Mode awal yang aman.
challenge Ban skor diubah menjadi challenge. Signature critical tetap diblokir.
enforce Semua keputusan dijalankan: challenge, blokir, dan ban.

Signature critical selalu diblokir di challenge dan enforce. Di observe, signature tetap dicatat tetapi tidak memblokir.

  • Denylist adalah pola yang Shield tolak (aturan bawaan).
  • Allowlist membuat host, path, atau IP melewati pemeriksaan signature dan perilaku. Pengecualiannya: signature critical tetap diproses dan dapat memblokir request.

Shield menghitung skor risiko untuk tiap request. Semakin mencurigakan, semakin tinggi skornya. Ambang batas menentukan keputusan:

public int $thresholdChallenge = 10; // mulai minta challenge
public int $thresholdBan = 20; // mulai ban
public int $thresholdStrongBan = 30; // ambang ban kuat

Request dengan skor 14 mendapat challenge; request dengan skor 25 mendapat ban. Saat ini thresholdStrongBan juga menghasilkan TEMP_BAN, bukan durasi yang otomatis lebih panjang. Durasi tetap ditentukan oleh jumlah offense dan banDurations.

Semua opsi di bawah sudah punya nilai bawaan yang aman untuk pertama kali dipasang. Anda tidak perlu mengatur semuanya di awal — baca shield:report beberapa hari dulu.

Konfigurasi bawaan sudah cukup untuk memulai. Kalau ingin menyesuaikan, buat file app/Config/Shield.php di aplikasi Anda yang mewarisi konfigurasi paket:

<?php
namespace Config;
class Shield extends \Ganadev\Shield\Codeigniter\Config\Shield
{
public string $mode = 'observe';
public array $sensitivePaths = ['/login', '/admin/login'];
public string $adminAuthorize = 'admin.authorize';
}

Kelas ini diambil otomatis oleh config('Shield'). Nilai yang tidak Anda tulis ulang memakai default bawaan. Jangan mewarisi BaseConfig langsung karena Anda akan kehilangan seluruh default Shield.

Karena config class mewarisi CodeIgniter\Config\BaseConfig, properti scalar bisa diganti dari .env tanpa memanggil env() di config class. Prefix pendek class Shield adalah shield (huruf kecil), dan nama properti harus sama persis dengan nama di class:

shield.mode = observe
shield.thresholdChallenge = 10
shield.challengeDriver = turnstile

Bentuk underscore juga dikenali:

shield_mode = observe
shield_thresholdChallenge = 10

Pengecualian: kunci challenge dibaca langsung oleh paket dengan getenv() dan tetap memakai nama uppercase:

SHIELD_TURNSTILE_SITE_KEY=0x4AAAAAAA...
SHIELD_TURNSTILE_SECRET_KEY=0x4AAAAAAA...
SHIELD_RECAPTCHA_SITE_KEY=...
SHIELD_RECAPTCHA_SECRET_KEY=...

Jangan memberi nilai default properti dengan env():

// Bukan PHP yang valid: memanggil fungsi di default properti.
public string $mode = env('SHIELD_MODE', 'observe');
// Benar: BaseConfig yang mengganti nilai dari .env.
public string $mode = 'observe';
Properti Default Untuk apa
enabled true Matikan seluruh Shield sekaligus.
mode observe observe (catat saja), challenge (ban menjadi challenge), atau enforce (jalankan semua keputusan).
appId 'my-app' Nama unik aplikasi Anda, tercatat di setiap kejadian.
responseCode 404 Kode status saat request diblokir. Umumnya ditolak halus sebagai 404 agar penyerang tidak tahu.
failMode 'open' open (lewati ban check) atau closed (blokir) saat lookup ban aktif gagal.
decodeDepth 2 Berapa kali URI di-decode sebelum dicocokkan dengan aturan.
  • open (default): kalau lookup ban aktif (findActiveByIp()) melempar exception, ban check dilewati dan infrastructureDegraded diset. Request tidak otomatis lolos — signature dan sinyal perilaku lain tetap dapat memblokir. Anda kehilangan proteksi berbasis ban, tapi situs tetap hidup.
  • closed: engine langsung membalas blokir dengan responseCode (default 404) dan skor 99 saat lookup ban aktif gagal. Jika exception infrastruktur lolos sampai ke filter, filter membalas 503 Service Unavailable. Situs bisa berhenti total — pilihan ini hanya untuk aplikasi yang keamanannya lebih penting daripada ketersediaannya.
Properti Default Untuk apa
thresholdBan 20 Skor yang memicu ban.
thresholdStrongBan 30 Ambang ban kuat. Saat ini tetap menghasilkan TEMP_BAN; durasi tidak otomatis lebih panjang.
banDurations [15, 60, 360, 1440] Durasi ban berjenjang (menit): 15, 1 jam, 6 jam, 24 jam.
escalationStep 5 Tambahan skor risiko per offense, dibatasi min(offenseCount, 5) * escalationStep. Bukan pengali durasi ban.
banCacheTtlSeconds 30 Berapa lama ban di-cache sebelum dicek ulang ke database.

Durasi ban dipilih dari banDurations memakai offenseCount - 1, lalu di-clamp ke durasi terakhir. offenseCount berasal dari ban sebelumnya; offense history tidak dihapus saat ban dirilis.

Properti Default Untuk apa
thresholdChallenge 10 Skor yang memicu challenge.
challengeDriver 'turnstile' turnstile, recaptcha, atau null / test (untuk development/testing).
trustedEnabled true Apakah pengunjung yang lolos challenge ditandai cookie agar tidak di-challenge ulang.
trustedTtlMinutes 60 Masa berlaku trusted cookie.

Driver dan kunci challenge diatur terpisah:

shield.challengeDriver = turnstile
SHIELD_TURNSTILE_SITE_KEY=0x4AAAAAAA...
SHIELD_TURNSTILE_SECRET_KEY=0x4AAAAAAA...

Nilai driver null, test, 0, atau string kosong memakai NullTestDriver. Nilai yang tidak dikenal tidak melempar error; Shield jatuh ke Turnstile. Jangan memakai SHIELD_CHALLENGE karena itu bukan nama properti challengeDriver.

Baca Challenge & Cookie untuk persiapannya.

Properti Default Untuk apa
uniqueUriLimit 25 Berapa banyak URL berbeda yang boleh diminta satu IP dalam satu jendela.
behaviorWindowSeconds 60 Panjang jendela waktu perhitungan perilaku.
notFoundLimit 20 Berapa banyak 404 yang boleh dihasilkan satu IP.
pathRateLimit 30 Batas request per path per jendela.
sensitivePathRateLimit 8 Batas request per path sensitif (mis. /login).
sensitivePaths ['/login', '/wp-login.php', ...] Path yang dianggap sensitif.
scannerUaSignal 4 Skor tambahan untuk User-Agent scanner (sqlmap, nikto, dll).
missingRefererSignal true Beri sinyal bila request tidak membawa Referer.
suspiciousUserAgents [] Marker substring UA tambahan yang memicu sinyal suspicious_user_agent (+2).
suspiciousUserAgentOverrides [] Tidak dipakai oleh core CI4; gunakan suspiciousUserAgents.
scannerUserAgents ['sqlmap', 'nikto', ...] Daftar UA scanner yang mendapat sinyal.

Paket tidak menyediakan opsi skipBehaviorCounters. skipPaths hanya melewati pemeriksaan body dan deteksi perilaku; counter unique dan path tetap naik sebelum keputusan dibuat. Untuk halaman publik yang sering diakses, gunakan pola gateSkipPaths + ShieldGateFilter yang dipakai default di Instalasi; penjelasannya ada di Registrasi & Urutan Filter.

Properti Default Untuk apa
botMode 'observe' observe (catat saja, aman untuk SEO), challenge, atau off.
crawlerVerificationEnabled true Verifikasi klaim “saya Googlebot” lewat DNS.
crawlerVerificationTtlHours 24 Berapa lama hasil verifikasi diingat.
crawlerHostnames ['googlebot' => [...], ...] Suffix host DNS untuk tiap crawler.
crawlerIpRanges [] Map ['googlebot' => ['203.0.113.0/24'], ...]; bukan list CIDR datar.
unverifiedClaimSignal 4 Skor tambahan untuk User-Agent bot yang belum terverifikasi.
knownBotAgents ['googlebot', 'bingbot', ...] Daftar bot yang dipercaya untuk verifikasi crawler (18 entri default).
ruleVersion '1.0.0' Versi rule pack yang dimuat.

crawlerIpRanges dicocokkan per nama agent. CIDR di bawah key yang salah tidak akan dipakai. Baca Perilaku & Bot untuk detailnya.

Properti Default Untuk apa
rulesPacksInjection true Aktifkan paket aturan injection (SQLi, XSS, RCE, dll).
rulesPacksWordpress false Aktifkan paket aturan WordPress.
bodyInspectionEnabled true Periksa isi body request (mendeteksi serangan di JSON).
bodyInspectionMaxBytes 65536 Batas body yang diperiksa (64 KB).
maxUriLength 2048 Panjang URI maksimal yang diproses.

Path yang bebas dari pemeriksaan body dan deteksi perilaku. Berguna untuk endpoint M2M atau webhook yang isinya teks bebas:

public array $skipPaths = [
'/api/webhooks/github',
'/api/webhooks/xendit',
];

Perhatikan: path yang di-skip tetap melewati pemeriksaan aturan dasar, hanya body dan deteksi perilaku yang dilewati.

Properti Default Untuk apa
apiPaths [] Prefix path yang diperlakukan sebagai API (mis. ['/api']).
apiDetectAccept true Otomatis anggap request dengan Accept: application/json sebagai API.

Untuk request yang terdeteksi sebagai API, respons blokir & challenge dikirim sebagai JSON — bukan HTML.

Properti Default Untuk apa
loggingLevel 'suspicious' all, suspicious, atau blocked — seberapa banyak yang dicatat.
logBypassEvents true Catat juga kejadian allowlist/trusted-cookie yang lolos.
retentionDays 30 Umur kejadian sebelum dihapus shield:prune.
sensitiveQueryParameters ['token', 'password', ...] Parameter query yang nilainya disamarkan di log.
Properti Default Untuk apa
adminEnabled false Nyalakan panel admin (default nonaktif).
adminAuthorize '' Permission yang dibutuhkan (mis. 'admin.authorize'). Kosong = siapa saja bisa membuka admin, bukan hanya user login.
adminPrefix 'shield' Prefix URL panel admin.

Baca Admin API sebelum menyalakannya.

Properti Default Untuk apa
blockedView 'shield/blocked' View halaman blokir.
challengeView 'shield/challenge' View halaman challenge.
brandingTitle 'Ganadev CodeIgniter Shield' Judul di halaman blokir/challenge.
brandingAccentColor '#22d3ee' Warna aksen.
brandingBackgroundColor '#0b1220' Warna latar.
brandingShowRuleId false Tampilkan ID rule di halaman blokir (untuk debugging).
Properti Default Untuk apa
allowlistHosts [] Host yang selalu lolos.
allowlistPaths [] Prefix path yang melewati signature non-critical dan deteksi perilaku.
allowlistIps [] IP yang selalu lolos.

Signature critical tetap diproses meskipun host/path/IP ada di allowlist. Untuk item non-critical, allowlist melewati pemeriksaan signature dan perilaku. Jangan meng-allowlist path yang memuat input dari internet tanpa berpikir panjang.

allowlistPaths dicocokkan dengan str_starts_with polos, bukan per segmen. /api/health juga cocok dengan /api/healthcheck. Jika ingin hanya path dan anak-anaknya, pakai trailing slash (/api/health/) dan tambahkan path persisnya bila perlu.

<?php
namespace Config;
class Shield extends \Ganadev\Shield\Codeigniter\Config\Shield
{
public string $mode = 'observe'; // naikkan ke 'enforce' setelah yakin
public string $appId = 'toko-online-saya';
public string $failMode = 'open';
public array $sensitivePaths = ['/login', '/admin/login', '/api/auth'];
public string $botMode = 'observe';
public array $skipPaths = ['/api/webhooks/github'];
public array $apiPaths = ['/api'];
public string $adminAuthorize = 'admin.authorize';
public int $retentionDays = 14;
}

Setelah mengubah konfigurasi, pastikan benar-benar terpakai dengan:

Terminal window
php spark shield:rules:list
php spark shield:health

Powered by PT Ganadev Multi Solusi