Lewati ke konten

Shield Corev1.2.x

Instalasi

import { Tabs, TabItem } from ‘@astrojs/starlight/components’;

Shield Core dibuat untuk project PHP yang tidak memakai Laravel. Kalau Anda memakai Laravel, jangan pasang ini sendiri — Laravel Shield sudah menariknya sebagai dependensi dan mengemas semua lapisan adapter.

  • PHP ^8.2
  • Composer

Tidak ada framework, tidak ada driver database, tidak ada pustaka pihak ketiga. Kalau composer install menarik sesuatu selain shield-core, berarti ada yang salah.

Terminal window
composer require ganadev/shield-core

Autoload memakai PSR-4 Ganadev\Shield\Core\ ke direktori src/.

Kalau Anda butuh salinan lokal:

Terminal window
git clone https://github.com/GanaDev-Com/shield-core.git

Tambahkan sebagai path repository di composer.json aplikasi Anda:

{
"repositories": [
{ "type": "path", "url": "../shield-core" }
]
}

Lalu composer require ganadev/shield-core:@dev.

Shield Core tidak memiliki penyimpanan. Ia meminta sesuatu dari Anda lewat interface, lalu Anda bebas memutuskan sendiri cara penyimpanannya — SQL, file, Redis, atau apa pun.

Interface Untuk apa
EventRepositoryInterface Mencatat setiap kejadian keamanan.
ClockInterface Menyediakan “sekarang”. Ada supaya tes bisa memakai waktu palsu.
Interface Kalau tidak diimplementasikan
BanRepositoryInterface Ban tidak pernah ditegakkan antar request, hanya dalam satu request.
CrawlerVerifierInterface Verifikasi crawler lewat DNS dilewati; yang mengaku bot diperlakukan sebagai browser biasa.
TrustedCookieInterface Pengguna yang lolos challenge harus mengulang challenge di request berikutnya.
Interface Peran
CacheAdapterInterface Cache untuk counter perilaku dan cache ban.
ChallengeDriverInterface Render dan verifikasi challenge (Turnstile, reCAPTCHA, atau apa pun).

Mesinnya sendiri butuh dua yang wajib; sisanya opsional dan bisa null.

Semua kontrak menerima request yang sudah dinormalkan, jadi Anda bisa mengimplementasikan sesederhana mungkin:

use Ganadev\Shield\Core\Clock\ClockInterface;
use Ganadev\Shield\Core\Persistence\EventRepositoryInterface;
use Ganadev\Shield\Core\Events\SecurityEvent;
final class SystemClock implements ClockInterface
{
public function now(): \DateTimeImmutable
{
return new \DateTimeImmutable;
}
}
final class NullEventLog implements EventRepositoryInterface
{
public function record(SecurityEvent $event): void
{
// Buang saja kalau Anda sedang mencoba-coba.
}
public function pruneOlderThan(\DateTimeImmutable $cutoff): int
{
return 0;
}
}

NullEventLog berguna untuk pengujian: kalau Shield memberi hasil yang tidak seperti seharusnya, sementara catatan kejadiannya bisa dibaca, hampir pasti bug.

Constructor ShieldEngine menerima sebelas collaborator secara positional. Semuanya dibangun di luar, jadi Anda bebas menguji setiap bagiannya sendiri.

use Ganadev\Shield\Core\Config\ShieldConfig;
use Ganadev\Shield\Core\Context\RequestContext;
use Ganadev\Shield\Core\Decision\DecisionEngine;
use Ganadev\Shield\Core\Detection\BehaviorDetector;
use Ganadev\Shield\Core\Detection\ThreatSignatureEngine;
use Ganadev\Shield\Core\Engine\ShieldEngine;
use Ganadev\Shield\Core\Normalization\Normalizer;
use Ganadev\Shield\Core\Reputation\BanPolicy;
use Ganadev\Shield\Core\Reputation\RiskDecay;
use Ganadev\Shield\Core\Rules\RuleRepository;
use Ganadev\Shield\Core\Scoring\RiskScorer;
$config = ShieldConfig::fromArray(require 'shield.php');
$engine = new ShieldEngine(
config: $config,
normalizer: new Normalizer(),
signatures: new ThreatSignatureEngine(new RuleRepository($config->rules)),
behavior: new BehaviorDetector($crawlerVerifier),
scorer: new RiskScorer(),
decisionEngine: new DecisionEngine(),
banPolicy: new BanPolicy(),
riskDecay: new RiskDecay(),
events: $eventLog,
clock: $clock,
bans: $banRepository, // boleh null
trusted: $trustedCookie, // boleh null
);

Tiga collaborator — RiskScorer, BanPolicy, dan RiskDecay — sengaja dibuat tanpa state. Masing-masing membaca konfigurasi dari argumen method yang menerima, bukan dari constructor. Jadi instance-nya aman dipakai ulang di seluruh request.

Satu request, satu hasil:

use Ganadev\Shield\Core\Context\RequestContext;
use Ganadev\Shield\Core\Detection\BehaviorCounters;
$context = RequestContext::create(
rawUri: $request->getRequestUri(),
method: $request->getMethod(),
host: $request->getHost(),
ip: $clientIp,
headersSubset: [
'user-agent' => $request->getUserAgent() ?? '',
'accept' => $request->getHeader('accept'),
'referer' => $request->getHeader('referer'),
],
body: $rawBody,
);
$result = $engine->inspect($context, $counters);

Yang perlu Anda periksa dari EngineResult:

$result->verdict->decision; // Decision yang diambil
$result->verdict->reason; // alasan yang bisa dibaca manusia
$result->score->total; // skor risiko
$result->matches; // rule yang cocok
$result->activeBan; // ban yang sedang berlaku
$result->trusted; // pengenal dari cookie tepercaya
$result->infrastructureDegraded; // salah satu contract gagal

Tiga method pintasan tersedia: shouldBlock(), shouldChallenge(), dan allowed().

Kalau Anda ingin melihat Shield bekerja sebelum menulis adapter, ini program lengkap tanpa framework:

<?php
require 'vendor/autoload.php';
use Ganadev\Shield\Core\Clock\SystemClock;
use Ganadev\Shield\Core\Config\ShieldConfig;
use Ganadev\Shield\Core\Context\RequestContext;
use Ganadev\Shield\Core\Decision\DecisionEngine;
use Ganadev\Shield\Core\Detection\BehaviorCounters;
use Ganadev\Shield\Core\Detection\ThreatSignatureEngine;
use Ganadev\Shield\Core\Engine\ShieldEngine;
use Ganadev\Shield\Core\Normalization\Normalizer;
use Ganadev\Shield\Core\Persistence\EventRepositoryInterface;
use Ganadev\Shield\Core\Reputation\BanPolicy;
use Ganadev\Shield\Core\Reputation\RiskDecay;
use Ganadev\Shield\Core\Rules\RuleRepository;
use Ganadev\Shield\Core\Scoring\RiskScorer;
$config = ShieldConfig::fromArray(require 'shield.php');
$engine = new ShieldEngine(
$config,
new Normalizer,
new ThreatSignatureEngine(new RuleRepository($config->rules)),
new BehaviorDetector,
new RiskScorer,
new DecisionEngine,
new BanPolicy,
new RiskDecay,
new class implements EventRepositoryInterface {
public function record(\Ganadev\Shield\Core\Events\SecurityEvent $event): void {}
public function pruneOlderThan(\DateTimeImmutable $cutoff): int { return 0; }
},
new SystemClock,
);
$result = $engine->inspect(
RequestContext::create('/.env', 'GET', 'contoh.test', '203.0.113.9'),
new BehaviorCounters,
);
echo $result->verdict->decision->value, PHP_EOL;
echo $result->verdict->reason, PHP_EOL;

Keluaran untuk /.env:

TEMP_BAN
critical: sensitive.env

Repository-nya punya beberapa perkakas yang berguna saat Anda mengerjakan adapter:

Terminal window
composer test # Pest
composer analyse # PHPStan level 8
composer format-test # Pint, hanya memeriksa
composer mutate # mutation testing
php tools/scanner-simulator/simulate.php # pemutaran ulang corpus scanner
php tools/scanner-simulator/benchmark.php # latensi jalur allow, target < 2 ms
php tools/replay.php # deteksi ulang dari log kejadian nyata

benchmark.php paling berguna untuk adapter Anda: jalankan setelah setiap perubahan, karena Shield dipanggil di setiap request.

  • Membuat Adapter — langkah berikutnya kalau framework Anda bukan Laravel.
  • Arsitektur — apa yang terjadi di dalam inspect().

Powered by PT Ganadev Multi Solusi