
وسيط Laravel سلبي يكتشف ويسجّل حقن SQL وXSS وRCE وماسحات البوتات وأكثر من 175 نمط هجوم. يتضمن لوحة تحكم مدمجة، وتنبيهات Slack، وواجهة REST API، وإثراءً جغرافيًا. نظام IDS، وليس WAF.
مراقبة أمنية وتسجيل هجمات لتطبيقات Laravel. اكتشف وسجّل حقن SQL،
XSS، RCE، اجتياز الدلائل، ماسحات الروبوتات واستطلاعات نمط /wp-admin —
كل طلب عدائي يُسجَّل في قاعدة بياناتك مع سياق التطبيق الكامل.
إنه نظام كشف اختراق (IDS)، وليس جدار حماية للتطبيقات (WAF): لا يحظر أو يصفّي أو يعدّل أي طلب أبدًا.
GET /wp-admin/setup-config.php 404 — on a site that isn't WordPress GET /.env 404 — someone wants your database password GET /?id=1' UNION SELECT password FROM 200 — SQL injection against a real route GET /phpmyadmin/index.php 404 — scanning for an admin panel
تلك الطلبات تصل بالفعل إلى تطبيق Laravel الخاص بك. يُظهر سجل الوصول لديك عنوان URL
ورمز الحالة فقط، ولا شيء آخر — لا الحمولة المفكوكة، ولا أي من مساراتك
كان مستهدفًا، ولا ما إذا كان نفس عنوان IP قد جرّب أربعين شيئًا آخر خلال هذه الساعة.
يجيب هذا الحزمة على تلك الأسئلة. قم بإسقاطها في أي تطبيق Laravel 10–13 وستبدأ
بفحص كل طلب HTTP مقابل أكثر من 150 نمط هجوم، مع تسجيل كل تطابق حسب
درجة الثقة وكتابته في قاعدة البيانات الخاصة بك — مع لوحة تحكم مدمجة، وتنبيهات Slack،
وإثراء جغرافي، وتصديرات fail2ban/قوائم الحظر. لا يتم حظر أي طلب أبدًا. فكّر في
كاميرا مراقبة، وليس قفلًا: فهي تُظهر لك بالضبط من يختبر مساراتك، وكم
مرة، وبأي تقنيات.
> مستخرجة من تطبيق إنتاجي ومُختبَرة على حركة مرور حقيقية. 335 اختبارًا، بدون تبعيات
> وقت تشغيل تتجاوز Laravel نفسه، ولا حاجة لاتصال بالإنترنت للكشف.
>
> هل تريد الترقية؟ راجع [UPGRADING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/UPGRADING.md). هل تريد المساهمة؟ راجع [CONTRIBUTING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/CONTRIBUTING.md).
## ابدأ في أقل من دقيقة```bash
composer require jayanta/laravel-threat-detection
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
ثم أضف الوسيط (middleware) إلى مجموعة web الخاصة بك (سطر واحد في bootstrap/app.php على Laravel 11+،
أو app/Http/Kernel.php على Laravel 10) — المقتطف الكامل في Quick Start أدناه.
هذا كل شيء؛ أصبح الكشف فعّالًا الآن.```bash
php artisan threat-detection:doctor # confirms it is actually recording
---
## أين يتناسب: IDS مقابل WAF مقابل الحافة
هذه الحزمة هي **IDS سلبي على مستوى التطبيق** — تراقب وتسجّل، ولا تمنع.
مصممة لتكون *بجانب* WAF أو خدمة الحافة، وليس بديلاً عنها. كل طبقة ترى
ما لا تستطيع الطبقات الأخرى رؤيته:
| | **هذه الحزمة** (IDS للتطبيق) | **WAF** (mod_security, Cloudflare WAF) | **الحافة / CDN** (Cloudflare) |
|---|:---:|:---:|:---:|
| تمنع الطلبات الخبيثة | ❌ تسجيل فقط | ✅ | ✅ |
| سياق تطبيق كامل (المسار الدقيق، الحمولة المفكوكة، المستخدم الموثّق) | ✅ | ⚠️ جزئي | ❌ |
| لوحة تحكم مدمجة + سجل تهديدات في قاعدة بياناتك | ✅ | ⚠️ يختلف | ⚠️ الحافة فقط |
| كشف خاص بالتطبيق (مثل Aadhaar / PAN / IFSC PII) | ✅ أنماط مخصصة | ❌ | ❌ |
| يعمل دون اتصال / بدون خدمة خارجية | ✅ | ⚠️ يعتمد | ❌ |
| يوقف حركة المرور قبل وصولها إلى تطبيقك | ❌ | ✅ الحافة | ✅ |
| الإعداد | `composer require` واحدة | متوسط–مرتفع | منخفض–متوسط |
| التكلفة | مجاني، MIT | يختلف | طبقة مجانية + مدفوعة |
**الخلاصة المختصرة:** الحافة/WAF هي قفل بابك؛ هذه هي كاميرا المراقبة
*الداخلية*، مع سياق التطبيق لتخبرك بالضبط ما الذي يُحاول تنفيذه على أي مسار،
بواسطة من، وكم مرة. استخدمها لتغذية قرارات حقيقية — حظر fail2ban، حدود المعدل،
الحظر الجغرافي — ببيانات لا تراها طبقة الحافة أبداً.
### ما ليست عليه عمداً
- **ليست WAF.** لا تمنع أو تصفّي أو تعدّل أي طلب أبداً. استخدم Cloudflare أو
mod_security أو WAF حقيقي للتنفيذ. (لا توجد طبقة حافة للتسليم إليها؟ إن
[المساعدات على جانب المشغّل](#acting-on-the-data-operator-side-blocking) تكشف
قرارات الحزمة حتى تتمكن من كتابة وسيط حظر خاص بك من خمسة أسطر —
كود التنفيذ يبقى ملكك، وليس ملك الحزمة.)
- **ليست بديلاً عن البرمجة الآمنة.** الاستعلامات المعلمة، والتحقق من المدخلات،
وهروب المخرجات هي دفاعاتك الفعلية. تفترض هذه الحزمة أن كودك آمن بالفعل
وتمنحك *رؤية*، وليس حماية.
- **ليست خدمة حافة.** إذا كان بإمكانك وضع Cloudflare في المقدمة، فافعل — ثم أضف
هذه للحصول على التفاصيل على مستوى التطبيق التي لا تستطيع خدمات الحافة رؤيتها.
### إذن ماذا تفعل بها فعلياً؟
السؤال الأكثر شيوعاً حول كاشف لا يمنع أبداً. أربع إجابات، بترتيب
متزايد للجهد:
| تريد أن | استخدم | الجهد |
|---|---|---|
| ترى ما يهاجمك | [لوحة التحكم](#dashboard) أو `threat-detection:stats` | لا شيء، يعمل بالفعل |
| تحظر المخالفين المتكررين عند جدار الحماية | [`threat-detection:export-fail2ban`](#artisan-commands) — وجّهه إلى cron | سطر واحد |
| ترفض عند خادم الويب | [`threat-detection:export-blocklist`](#artisan-commands) → توجيهات nginx/apache | سطر واحد |
| ترفض الطلبات داخل التطبيق | [المساعدات على جانب المشغّل](#acting-on-the-data-operator-side-blocking) — `isBlocklisted()`، `isDdosThresholdExceeded()` | ~10 أسطر من الوسيط الخاص بك |
| تتفاعل في الوقت الفعلي | [حدث `ThreatDetected`](#threatdetected-event) — Telegram، SIEM، PagerDuty | مستمع |
الحزمة توفّر الذكاء؛ أنت توفّر الرفض. هذا التقسيم
متعمّد — كود التنفيذ الذي يعيش في تطبيقك هو كود يمكنك قراءته
واختباره وإيقافه، ويعني أن خطأ الكشف لا يمكن أن يُسقط موقعك أبداً.
### كيف تقارن بحزم أمان Laravel الأخرى
هذه الحلول تحل مشاكل مختلفة وتتكامل جيداً — الجدول يدور حول اختيار
الأداة الصحيحة، وليس الفوز.
| الحزمة | ما تفعله | تمنع؟ | استخدمها عندما |
|---|---|:---:|---|
| **هذه الحزمة** | تفحص كل طلب مقابل 150+ نمطاً، وتسجّل بسياق تطبيق كامل | ❌ | تريد أن *ترى* ما يُحاول تنفيذه على تطبيقك |
| `spatie/laravel-honeypot` | حقل نموذج مخفي يلتقط روبوتات البريد العشوائي | ✅ نموذج فقط | لديك نماذج عامة تتعرض للبريد العشوائي |
| `graham-campbell/security` | يزيل ترميز XSS-ish من المدخلات | ✅ يعدّل | تريد تنظيف مدخلات ساذج |
| `spatie/laravel-csp` | يرسل ترويسات Content-Security-Policy | ✅ المتصفح | تريد تقييد ما يحمّله المتصفح |
| `laravel/fortify` + حدود المعدل | تقييد المصادقة والقفل | ✅ | تحتاج حماية القوة الغاشمة على تسجيل الدخول |
| Cloudflare / mod_security | WAF حافة، يمنع قبل تطبيقك | ✅ | تريد إيقاف حركة المرور قبل وصولها |
الخلاصة الصادقة: مصيدة العسل تلتقط بريد النماذج العشوائي، وWAF يمنع حركة
المرور المعروفة بالخطر عند الحافة، وCSP يقيّد المتصفح. **لا يخبرك أي منها
بما حاول المهاجم تنفيذه ضد مساراتك المحددة، مع الحمولة المفكوكة
والمستخدم الموثّق المرفق.** تلك الفجوة هي ما تملؤه هذه الحزمة — ولهذا
لا تمنع الحزمة عمداً: يمكنك تشغيلها بجانب كل ما سبق
دون أن تتعارض أي منها مع الأخرى.
---
## المتطلبات
- PHP 8.2+ (Laravel 13 يتطلب PHP 8.3+)
- Laravel 10.x أو 11.x أو 12.x أو 13.x
- أي قاعدة بيانات يدعمها Laravel (MySQL, PostgreSQL, SQLite, SQL Server)
- أي برنامج تشغيل للذاكرة المؤقتة — **لا يتطلب Redis أو عامل قائمة انتظار**. Redis/Memcached
*موصى به* فقط لتفعيل فحص DDoS الاختياري (الذي يُعطّل تلقائياً على
برامج التشغيل غير الذرية). الكتابات في قائمة الانتظار اختيارية ومعطّلة افتراضياً.
---
## كيف يعمل
1. وسيط يفحص كل طلب HTTP وارد
2. يُفحص الطلب مقابل 158 نمطاً regex تغطي حقن SQL وXSS وRCE وتجاوز الملفات وSSRF وLDAP وXPath وSSTI والمزيد
3. إذا تطابق نمط تهديد، يُكتب سجل في جدول قاعدة البيانات `threat_logs` الخاص بك مع عنوان IP وعنوان URL ونوع التهديد ومستوى الخطورة ودرجة الثقة
4. اختيارياً، يُرسل تنبيه Slack للتهديدات عالية الخطورة
5. يستمر الطلب بشكل طبيعي — **لا يتم حظر أي شيء**
لا حاجة لاتصال بالإنترنت للكشف.
---
## بدء سريع
### 1. تثبيت الحزمة```bash
composer require jayanta/laravel-threat-detection
هذه الخطوة مطلوبة. بدونها، سيكتشف الحزمة التهديدات لكنها لن تستطيع تخزينها في قاعدة البيانات. إذا تخطيت هذه الخطوة، فلن يكون جدول
threat_logsموجودًا وستفقد جميع عمليات الكشف بصمت (سترى فقط أخطاءً فيstorage/logs/laravel.log).```bash php artisan vendor:publish --tag=threat-detection-migrations php artisan migrate
ينشئ هذا جدولين: `threat_logs` (يخزن التهديدات المكتشفة) و`threat_exclusion_rules` (يخزن قواعد النتائج الإيجابية الخاطئة).
**تحقق من إنشاء الجداول:**```bash
php artisan migrate:status
ابحث عن create_threat_logs_table وadd_confidence_to_threat_logs_table وcreate_threat_exclusion_rules_table - يجب أن تظهر جميعها بحالة Ran.
الوسيط هو ما يقوم بفحص الطلبات. تحتاج إلى إضافته إلى مجموعة وسائط web الخاصة بك.
إذا كنت تستخدم Laravel 11 أو 12 - افتح bootstrap/app.php:```php
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
\JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
]);
})
> **كيف تتحقق من إصدار Laravel لديك:** شغّل `php artisan --version` في الطرفية.
**إذا كنت تستخدم Laravel 10** - افتح `app/Http/Kernel.php`:```php
protected $middlewareGroups = [
'web' => [
// ... existing middleware
\JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
],
];
php artisan vendor:publish --tag=threat-detection-config
الحزمة تعمل بإعدادات افتراضية منطقية. نشر الإعدادات يتيح لك تخصيص أنماط الكشف، أوضاع الحساسية، إشعارات Slack، والمزيد. إذا تخطيت هذه الخطوة، كل شيء لا يزال يعمل.
**هذا كل شيء.** تطبيقك الآن يكتشف التهديدات.
---
## التحقق من أنها تعمل
بعد التثبيت، قم بتشغيل تهديد تجريبي وتأكد من أنه تم تسجيله.
### الخطوة 1: تشغيل تطبيقك```bash
php artisan serve
أضف معامل استعلام ضار إلى أي مسار موجود في تطبيقك (صفحتك الرئيسية، صفحة منتج، إلخ). على سبيل المثال:
حقن SQL:``` http://localhost:8000/?q=' UNION SELECT * FROM users--
**XSS (البرمجة النصية عبر المواقع):**```
http://localhost:8000/?q=<script>alert(1)</script>
اجتياز الدليل:``` http://localhost:8000/?file=../../etc/passwd
**RCE (تنفيذ التعليمات البرمجية عن بُعد):**```
http://localhost:8000/?cmd=system('ls -la')
شيلشوك (CVE-2014-6271):``` http://localhost:8000/?cmd=() { :;}; /bin/bash
**حقن أوامر ويندوز:**```
http://localhost:8000/?cmd=powershell -c whoami
DROP TABLE (SQL DDL):``` http://localhost:8000/?q=DROP TABLE users
> استخدم مسارًا موجودًا فعليًا في تطبيقك (مثل `/`). إذا أعاد عنوان URL خطأ 404، فقد لا يكون الوسيط (middleware) قد تم تنفيذه.
### الخطوة 3: تحقق من تسجيل التهديدات
**الخيار أ - أمر Artisan (الأسرع):**```bash
php artisan threat-detection:stats
الخيار ب - Tinker:```bash php artisan tinker
```php
DB::table('threat_logs')->latest()->take(5)->get(['ip_address', 'type', 'threat_level', 'confidence_score']);
الخيار C - ملف سجل Laravel:
يتم كتابة كل تهديد تم اكتشافه كتحذير إلى storage/logs/laravel.log:```
[high] Threat Detected: [middleware] SQL Injection UNION from 127.0.0.1 (http://localhost:8000/?q=...) [confidence: 50%]
### أشياء يجب معرفتها عند الاختبار
| السلوك | الشرح |
|----------|-------------|
| نفس التهديد يُسجَّل مرة واحدة فقط كل 5 دقائق | إزالة التكرار: نفس عنوان IP + نفس نوع التهديد يتم تخزينهما مؤقتًا لمدة 5 دقائق. استخدم **أنواع هجمات مختلفة** لكل اختبار، أو انتظر بين الاختبارات. |
| طلبات `curl` تُطلق كشفًا إضافيًا | استخدام `curl` يُسجّل أيضًا كشف "cURL Command" لوكيل المستخدم (بأهمية منخفضة). هذا متوقع - الحزمة تكتشف الأدوات الآلية. |
| الحزمة لا تحظر الطلبات أبدًا | يستمر تطبيقك في العمل بشكل طبيعي. الكشف سلبي. |
| لا حاجة لإعداد Slack | الإشعارات معطّلة افتراضيًا. |
| لا حاجة لاتصال بالإنترنت | الكشف الأساسي محلي 100%. فقط الأمر الاختياري `threat-detection:enrich` يستدعي واجهة برمجة تطبيقات خارجية لبيانات الجغرافيا. |
### استكشاف الأخطاء وإصلاحها
**ابدأ من هنا — أمر واحد يجيب عن معظم هذا:**```bash
php artisan threat-detection:doctor
يتحقق من الأشياء التي تجعل الكشف يفشل بصمت — حيث تبقى لوحة التحكم فارغة، وهو ما يبدو مطابقًا لـ "لا هجمات" — ويطبع الإصلاح الدقيق لكل حالة. ويخرج برمز غير صفري عند فشل حقيقي، لذا فهو آمن للتشغيل في CI أو خطوة نشر.``` Threat Detection — health check
PASS Detection is enabled for this environment FAIL 'threat_logs' is missing confidence_label — EVERY threat is being discarded Run: php artisan vendor:publish --tag=threat-detection-migrations && php artisan migrate WARN 1 custom pattern(s) shadow a built-in: Localhost SSRF Your copy runs instead of the maintained one, so later fixes to it never reach you.
ما الذي يغطيه: الكشف المُفعّل لهذه البيئة؛ كل عمود يحتاجه الكاتب (أي عمود مفقود يتجاهل **كل** تهديد)؛ أعمدة لوحة التحكم/الواجهة البرمجية؛ جدول قواعد الاستثناء؛ ما إذا كانت الوسيطة (middleware) موصولة فعليًا بمسار أو مجموعة؛ الإعدادات المنشورة التي تسبق هذا الإصدار؛ الأنماط المخصصة التي تحجب الأنماط المدمجة؛ برنامج تشغيل ذاكرة التخزين المؤقت الذي لا يمكنه إجراء عدّ DDoS؛ ولوحة تحكم أو واجهة برمجية تُركت مفتوحة دون مصادقة.
**"لقد اختبرت لكن `threat-detection:stats` يُظهر صفر تهديدات" / "التهديدات لا تُخزَّن في قاعدة البيانات"**
إذا اجتاز الفحص (doctor)، فالتثبيت سليم والمشكلة تكمن في طلب الاختبار نفسه. ثلاثة أشياء لا يمكنه التحقق منها نيابةً عنك:
| الفحص | كيفية التحقق |
|-------|---------------|
| عنوان IP غير مُدرج في القائمة البيضاء | إذا أضفت `THREAT_DETECTION_WHITELISTED_IPS` إلى `.env`، فقم بإزالته أثناء الاختبار |
| استخدام مسار موجود | يجب أن يتطابق رابط الاختبار مع مسار حقيقي (مثل `/`). رمز 404 يعني أن الوسيطة لم تعمل أبدًا |
| ذاكرة التخزين المؤقت للتكرار | نفس عنوان IP + نفس نوع الهجوم يُخزَّن مؤقتًا لمدة 5 دقائق - جرّب نوع هجوم مختلف |
> تشغيل `php artisan migrate` وحده لا يكفي أبدًا: ملفات الترحيل موجودة داخل الحزمة ويجب نشرها إلى مجلد `database/migrations/` في تطبيقك أولاً. يطبع الفحص (doctor) الأمر الدقيق عندما تكون هذه هي المشكلة.
**"الواجهة البرمجية تُرجع 401 غير مصرح به"**
انظر [مصادقة الواجهة البرمجية](#api-authentication) أدناه.
**"لوحة التحكم تُظهر 404"**
لوحة التحكم معطّلة افتراضيًا. أضف `THREAT_DETECTION_DASHBOARD=true` إلى `.env` وامسح ذاكرة التخزين المؤقت للمسارات:```bash
php artisan route:clear
/wp-admin، /.env، /phpmyadmin، /actuator، إلخ) مع أكثر من 50 مسار استطلاع افتراضيًاapplication/json)تعمل الحزمة دون أي تغييرات في .env. جميع القيم أدناه اختيارية - أضفها فقط إذا كنت تريد تجاوز الإعدادات الافتراضية.```env
THREAT_DETECTION_ENABLED=true
THREAT_DETECTION_MODE=balanced
### أوضاع الكشف
| الوضع | عتبة الثقة | السلوك |
|------|---------------------|----------|
| `strict` | 0 (يسجل كل شيء) | جميع الأنماط نشطة، أدنى العتبات. يلتقط كل شيء لكنه قد يعلّم حركة المرور المشروعة. |
| `balanced` | 10 | الافتراضي. تسجيل الثقة نشط، عتبات قياسية. مناسب لمعظم التطبيقات. |
| `relaxed` | 40 | فقط الأنماط عالية الخطورة تُفعَّل. الأفضل للمواقع كثيفة المحتوى ذات النتائج الإيجابية الكاذبة المتكررة. |
### البيئات المفعّلة
افتراضيًا، يعمل الكشف في `production` و`staging` و`local`. للتغيير، انشر الإعداد وعدّله:```php
'enabled_environments' => ['production', 'staging', 'local'],
لتعطيل الكشف في مجموعة الاختبارات الخاصة بك، قم بتعيين APP_ENV=testing (وليس في القائمة أعلاه) أو أضف إلى ملف phpunit.xml الخاص بك:```xml
### مرجع الإعدادات
انشر ملف الإعدادات لرؤية جميع الخيارات المتاحة:```bash
php artisan vendor:publish --tag=threat-detection-config
Key config sections: skip_paths (المسارات المطلوب تخطيها)، only_paths (وضع القائمة البيضاء)، auth_paths (الكشف الذكي لمسارات تسجيل الدخول)، content_paths (كتم التنبيهات غير الحرجة)، safe_fields (استبعاد حقول محددة من الفحص)، safe_paths (استبعاد الحقول المرتبطة بالمسار لـ JSON المتداخل)، probe_tracking (كشف استكشاف 404)، context_weights (مضاعفات التقييم)، threat_levels (تعيين كلمات مفتاحية للخطورة)، api_route_filtering (كتم المنخفض/المتوسط على مسارات API)، queue (المعالجة غير المتزامنة)، retention (التنظيف التلقائي)، max_detections_per_request (حد الأداء)، dashboard.guard / (وضع المصادقة).
only_paths)إذا كان تطبيقك يحتوي على العديد من المسارات ولكنك تهتم فقط بعدد قليل منها، استخدم only_paths لفحص فقط تلك المسارات. يتم تخطي جميع المسارات الأخرى تلقائيًا - دون أي حمل إضافي من الوسيط (middleware) على الإطلاق.```php
// config/threat-detection.php
'only_paths' => [
'admin/',
'api/',
'login',
'register',
],
اتركه فارغًا (الافتراضي) لفحص جميع المسارات (خاضعًا لـ `skip_paths`). عند تكوين كلاهما، يتم التحقق من `only_paths` أولاً، ثم يتم تطبيق `skip_paths` ضمن المجموعة المطابقة.
### دعم قائمة الانتظار
بشكل افتراضي، يتم تسجيل التهديدات بشكل متزامن في دورة الطلب. بالنسبة للتطبيقات ذات الحركة المرورية العالية، يمكنك تفريغ عمليات كتابة قاعدة البيانات وإشعارات Slack إلى قائمة انتظار:```env
THREAT_DETECTION_QUEUE=true
THREAT_DETECTION_QUEUE_CONNECTION=redis
THREAT_DETECTION_QUEUE_NAME=threat-logs
يؤدي هذا إلى إرسال مهمة StoreThreatLog (3 محاولات إعادة، مهلة تراجع 10 ثوانٍ/30 ثانية). لا يزال الكشف يحدث في الوقت الفعلي - فقط عملية الكتابة هي المؤجلة.
حذف سجلات التهديدات القديمة تلقائيًا وفقًا لجدول زمني يومي:```env THREAT_DETECTION_RETENTION=true THREAT_DETECTION_RETENTION_DAYS=90
يتطلب تشغيل جدولة Laravel (`php artisan schedule:run`). يعمل يوميًا في الساعة 02:00 عبر `threat-detection:purge`.
### حدث ThreatDetected
كل تهديد مؤكد يطلق حدث `ThreatDetected` يمكنك الاستماع إليه:```php
// app/Providers/EventServiceProvider.php
use JayAnta\ThreatDetection\Events\ThreatDetected;
protected $listen = [
ThreatDetected::class => [
YourCustomListener::class,
],
];
الحدث يحمل $threatLog (مصفوفة صف قاعدة البيانات الكاملة)، و$ipAddress، و$threatLevel. استخدمه لتشغيل إجراءات مخصصة - إرسال تنبيهات Telegram، تحديث قائمة حظر، تغذية نظام SIEM، وما إلى ذلك.
عندما يتجاوز عميل حد DDoS المُهيأ (طلبات ddos.threshold خلال
ddos.window ثانية)، يتم إرسال حدث DdosThresholdExceeded جنبًا إلى جنب مع
إدخال سجل التهديد:```php
use JayAnta\ThreatDetection\Events\DdosThresholdExceeded;
protected $listen = [ DdosThresholdExceeded::class => [ YourFloodListener::class, ], ];
الحدث يحمل `$ipAddress` و `$requestCount` و `$threshold` و `$windowSeconds`. يتم
تقييده إلى مرة واحدة لكل عنوان IP لكل نافذة إلغاء تكرار (نفس التقييد المطبق على صف السجل)، لذا لا يمكن لفيضان
أن يغرق مستمعيك. استخدمه للتنبيه أو لتغذية مخزن حظر خارجي؛ لـ*رفض*
العملاء الذين تجاوزوا العتبة، استخدم `ThreatDetection::isDdosThresholdExceeded($ip)` من
الوسيط الخاص بك بدلاً من ذلك — راجع [التعامل مع البيانات](#acting-on-the-data-operator-side-blocking).
---
## إشعارات Slack
تنبيهات Slack معطلة افتراضيًا. لتفعيلها:```env
THREAT_DETECTION_NOTIFICATIONS=true
THREAT_DETECTION_SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
THREAT_DETECTION_SLACK_CHANNEL=#threat-alerts
فقط التهديدات عالية الخطورة تُطلق الإشعارات افتراضيًا (قابلة للتكوين عبر notify_levels في الإعدادات).
Laravel 10: يستخدم فئة الإشعارات المدمجة SlackMessage. لا حاجة لحزمة إضافية.
Laravel 11+: تمت إزالة قناة Slack المدمجة. تكتشف الحزمة ذلك تلقائيًا وترسل طلبات HTTP POST خام عبر webhooks إلى رابط Slack الخاص بك. لا حاجة لحزمة إضافية. إذا كنت تفضل قناة الإشعارات الكاملة، فثبّت:```bash composer require laravel/slack-notification-channel
---
## لوحة المعلومات
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/12500/fc7950bd0cc6323bcc2d62b03e31c99edc7450b0ef76f9cbfa5133b527b25269.png" alt="لوحة معلومات كشف التهديدات — إحصائيات، مخطط زمني لسبعة أيام، سجل تهديدات مباشر، أبرز عناوين IP المخالفة، والتهديدات حسب الدولة" width="100%">
</p>
تأتي الحزمة مع لوحة معلومات مدمجة بالوضع الداكن (Alpine.js + Tailwind CDN - لا تتطلب خطوة بناء).```
+-------------------------------------------------------------------------+
| Threat Detection Dashboard |
+-------------------------------------------------------------------------+
| Total: 847 | High: 23 | Med: 156 | Low: 668 | IPs: 94 |
+-------------------------------------------------------------------------+
| [Timeline Chart - 7 Day Stacked Bar] |
+-------------------------------------------------------------------------+
| Search: [___________] Level: [All] |
| Time IP Type Level Confidence Actions |
| Mar 2 14:02 185.220.101.4 SQL Injection HIGH 80% [FP] |
| Mar 2 13:58 45.33.32.156 XSS Script Tag HIGH 65% [FP] |
| Mar 2 13:45 192.168.1.10 Scanner: Nikto MED 35% [FP] |
+-------------------------------------------------------------------------+
| Top IPs | Threats by Country |
| 185.220.101.4 [23] | US 234 |
| 45.33.32.156 [18] | CN 156 |
| 103.152.220.1 [12] | RU 98 |
+-------------------------------------------------------------------------+
أضف إلى .env:```env
THREAT_DETECTION_DASHBOARD=true
قم بزيارة: `http://your-app.test/threat-detection`
### الدخول أثناء التطوير المحلي
تستخدم لوحة التحكم middleware `['web', 'auth']` افتراضيًا، لذا يجب أن يكون المستخدمون مسجلين الدخول. إذا لم يكن تطبيقك يحتوي على مصادقة بعد، فقم بتقييد الوصول إلى جهازك الخاص بدلاً من ذلك:```env
THREAT_DETECTION_DASHBOARD_GUARD=ip
THREAT_DETECTION_DASHBOARD_IPS=127.0.0.1
جميع خيارات الحماية، والحماية المنفصلة على نقاط النهاية التي تعطّل عمليات الكشف، مشمولة في مصادقة لوحة التحكم وواجهة برمجة التطبيقات.
إذا كانت لوحة التحكم تعرض بيانات فارغة، فهذا يعني أن الصفحة تم تحميلها ولكن استدعاءات واجهة برمجة التطبيقات الخاصة بها لم تنجح. راجع مصادقة واجهة برمجة التطبيقات.
توفر الحزمة 15 نقطة نهاية REST لبناء لوحات تحكم مخصصة أو عمليات تكامل.
تستخدم مسارات واجهة برمجة التطبيقات وسيط auth:sanctum افتراضيًا. تتعامل الحزمة مع هذا الأمر بسلاسة:
['api'] فقط. تعمل واجهة برمجة التطبيقات بدون مصادقة.إذا كنت لا تستخدم Sanctum ولكنك تريد حماية واجهة برمجة التطبيقات الخاصة بك، فلديك خياران:
الخيار 1 - استخدام حماية المصادقة المدمجة:```env THREAT_DETECTION_API_GUARD=auth
**الخيار 2 - تعديل البرمجية الوسيطة مباشرة:**```php
// config/threat-detection.php
'api' => [
'enabled' => true,
'prefix' => 'api/threat-detection',
'middleware' => ['api', 'auth'], // or 'auth:your-guard'
],
للاختبار المحلي (إذا كان Sanctum يمنع الوصول)، غيّر مؤقتًا:```php 'middleware' => ['api'], // remove 'auth:sanctum'
> استعادة المصادقة قبل النشر إلى بيئة الإنتاج.
### مرجع نقاط النهاية
| الطريقة | نقطة النهاية | الوصف |
|--------|----------|-------------|
| GET | `/api/threat-detection/threats` | قائمة التهديدات (مرتبة بالصفحات، قابلة للتصفية) |
| GET | `/api/threat-detection/threats/{id}` | تفاصيل تهديد واحد |
| POST | `/api/threat-detection/threats/{id}/false-positive` | وضع علامة على التهديد كإيجابية كاذبة |
| GET | `/api/threat-detection/stats` | إحصائيات عامة |
| GET | `/api/threat-detection/summary` | تحليل تفصيلي حسب النوع والمستوى وعنوان IP |
| GET | `/api/threat-detection/live-count` | التهديدات في الساعة الأخيرة |
| GET | `/api/threat-detection/by-country` | مجمعة حسب الدولة |
| GET | `/api/threat-detection/by-cloud-provider` | مجمعة حسب مزود الخدمة السحابية |
| GET | `/api/threat-detection/top-ips` | عناوين IP الأكثر مخالفة |
| GET | `/api/threat-detection/timeline` | الخط الزمني للتهديدات (للرسوم البيانية) |
| GET | `/api/threat-detection/ip-stats?ip=x.x.x.x` | إحصائيات لعنوان IP محدد |
| GET | `/api/threat-detection/correlation` | تحليل الارتباط |
| GET | `/api/threat-detection/export` | تصدير إلى CSV |
| GET | `/api/threat-detection/exclusion-rules` | قائمة قواعد الاستبعاد |
| DELETE | `/api/threat-detection/exclusion-rules/{id}` | حذف قاعدة استبعاد |
### معلمات الاستعلام لـ `/threats`
| المعلمة | الوصف |
|-----------|-------------|
| `keyword` | البحث في عنوان IP وعنوان URL والنوع |
| `ip` | التصفية حسب عنوان IP |
| `level` | التصفية حسب مستوى التهديد (`high`, `medium`, `low`) |
| `type` | التصفية حسب نوع التهديد |
| `country` | التصفية حسب رمز الدولة |
| `is_foreign` | تصفية عناوين IP الأجنبية (`true`/`false`) |
| `cloud_provider` | التصفية حسب مزود الخدمة السحابية |
| `is_false_positive` | التصفية حسب حالة الإيجابية الكاذبة (`true`/`false`) |
| `date_from` / `date_to` | تصفية نطاق التاريخ |
| `per_page` | العناصر لكل صفحة (الافتراضي: 20، الحد الأقصى: 100) |
### مثال على استجابة API
**GET `/api/threat-detection/stats`:**```json
{
"success": true,
"data": {
"total_threats": 847,
"high_severity": 23,
"medium_severity": 156,
"low_severity": 668,
"unique_ips": 94,
"foreign_ips": 67,
"cloud_attacks": 12,
"today": 34,
"last_hour": 5
}
}
Vue.js:```javascript async mounted() { const response = await fetch('/api/threat-detection/stats'); this.stats = await response.json();
const threats = await fetch('/api/threat-detection/threats?per_page=20');
this.threats = await threats.json();
}
**React:**```jsx
useEffect(() => {
fetch('/api/threat-detection/stats')
.then(res => res.json())
.then(data => setStats(data));
}, []);
إذا كانت واجهة برمجة التطبيقات (API) الخاصة بك تستخدم
auth:sanctum، فقم بتضمين رؤوس المصادقة أو قم بتكوين مصادقة Sanctum SPA للطلبات المستندة إلى ملفات تعريف الارتباط.
php artisan threat-detection:doctor
php artisan threat-detection:stats
php artisan threat-detection:enrich --days=7
php artisan threat-detection:purge --days=30
php artisan threat-detection:export-fail2ban --level=high --since=24h --min-hits=5 php artisan threat-detection:export-fail2ban --format=plain > /tmp/banlist.txt
php artisan threat-detection:export-blocklist --format=nginx > /etc/nginx/blocklist.conf php artisan threat-detection:export-blocklist --format=apache > .htaccess-deny php artisan threat-detection:export-blocklist --format=csv --since=7d
---
## التعامل مع البيانات (الحظر من جهة المشغّل)
لا تقوم الحزمة أبدًا بحظر أي طلب — فهذه هي هويتها، وليست إعدادًا افتراضيًا. التصديرات أعلاه
تغذّي طبقات الإنفاذ التي تشغّلها بالفعل (fail2ban، nginx، جدار حماية WAF عند الحافة). لكن بعض النشرات
لا تملك مثل هذه الطبقة لتغذيتها — الاستضافة المشتركة، PaaS، الحاويات خلف موازن تحميل لا
تتحكم فيه. لهذه الحالات، تعرض الحزمة *قراراتها* كأدوات مساعدة، وتكتب أنت
وسيط الإنفاذ بنفسك. نفس البنية المعمارية للتصديرات: **نحن نوفر
الذكاء، وأنت توفر الرفض.**```php
// app/Http/Middleware/EnforceThreatDecisions.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use JayAnta\ThreatDetection\Facades\ThreatDetection;
class EnforceThreatDecisions
{
public function handle(Request $request, Closure $next)
{
$ip = (string) $request->ip();
// Static operator denylist (config: blocklisted_ips).
// CIDR supported; whitelisted_ips wins on overlap.
if (ThreatDetection::isBlocklisted($ip)) {
abort(403);
}
// Volumetric flood: refuse over-threshold clients until the window resets.
if (ThreatDetection::isDdosThresholdExceeded($ip)) {
return response('Too Many Requests', 429, [
'Retry-After' => (string) config('threat-detection.ddos.window', 60),
]);
}
return $next($request);
}
}
قبل أن تفرض الحظر على IP، قم بتكوين
TrustProxies.كل ما سبق يعتمد على
$request->ip(). خلف موازن التحميل أو CDN أو الوكيل العكسي، فإن ذلك يُرجع عنوان IP العميل فقط عندما يتم إخبار Laravel بالوكلاء الذين يجب الوثوق بهم. إذا لم يتم ذلك، يحدث أمران في وقت واحد: كل طلب يبدو وكأنه قادم من الوكيل، لذا فإن إدخال قائمة الحظر يمنع كل حركة المرور أو لا يمنع شيئًا منها — والأسوأ، إذا وثقت التطبيق برأس توجيهي لا ينبغي له، يمكن للمهاجم تعيينX-Forwarded-Forوالمرور مباشرة عبر قائمة الحظر.هذا الأمر أكثر أهمية هنا من
whitelisted_ips. عدم تطابق قائمة السماح يعني فقط أن الحزمة تفحص طلبًا ربما كانت ستتخطاه: فهي تفشل بأمان. قائمة الحظر المستخدمة لرفض حركة المرور تفشل بشكل مفتوح — تعتقد أن عنوانًا محظورًا بينما هو ليس كذلك. تحقق منapp/Http/Middleware/TrustProxies.php(أو استدعاءtrustProxiesفيbootstrap/app.phpعلى Laravel 11+) قبل الاعتماد على أي من المساعدين لفرض الحظر.
قم بتسجيله عالميًا (من الجيد تسجيله قبل وسيط الكشف — المساعدون يقرؤون الإعدادات و الذاكرة المؤقتة، ولا يعتمدون على ترتيب الوسائط):```php // bootstrap/app.php (Laravel 11+) ->withMiddleware(function ($middleware) { $middleware->prepend(\App\Http\Middleware\EnforceThreatDecisions::class); })
المساعدات:
| المساعد | يُرجع | مدعوم بواسطة |
|---|---|---|
| `ThreatDetection::isBlocklisted($ip)` | `bool` | إعداد `blocklisted_ips` (CIDR عبر `IpUtils`؛ القائمة البيضاء لها الأولوية) |
| `ThreatDetection::isWhitelisted($ip)` | `bool` | إعداد `whitelisted_ips` |
| `ThreatDetection::ddosRequestCount($ip)` | `int` | عداد الفيضان الذي يحتفظ به وسيط الكشف |
| `ThreatDetection::isDdosThresholdExceeded($ip)` | `bool` | ذلك العداد مقابل `ddos.threshold` |
ملاحظات:
- **قائمة الحظر ثابتة ويشرف عليها المشغّل.** لا شيء في الحزمة يضيف إليها أبدًا —
فهي تنفّذ نفس القرار الذي كان سينفّذه سجن fail2ban ("قرأت لوحة التحكم؛ هذا النطاق /24
معادٍ")، لكن داخل التطبيق فقط.
- عداد DDoS يحسب فقط الطلبات التي وصلت إلى الكشف (`skip_paths`، وعناوين IP في القائمة
البيضاء، والبيئات المعطّلة لا تُحسب أبدًا)، ويبقى عند 0 على برامج تشغيل التخزين المؤقت حيث
يكون كشف DDoS معطّلًا (`file`، `database`، `null`).
- عندما يتجاوز العميل الحد الأدنى، يتم أيضًا إرسال حدث [`DdosThresholdExceeded`](#ddosthresholdexceeded-event)
— مفيد للتنبيه أو لتغذية قائمة حظر خارجية. لكن لا تستدعِ `abort()`
من المستمع: فالمستمعون يعملون داخل كتلة `try/catch` ذات الفتح عند الفشل الخاصة بوسيط الكشف،
لذا فإن الرفض ينتمي إلى الوسيط الخاص بك كما هو موضح أعلاه.
---
## تتبّع استطلاعات 404
تكتشف الحزمة استطلاعات الاستطلاع - وهي روبوتات تضرب مسارات معروفة وقابلة للاستغلال مثل `/wp-admin` أو `/.env` أو `/phpmyadmin` على موقعك غير المخصص لـ WordPress أو phpMyAdmin. لا تحمل هذه أي حمولة خبيثة؛ المسار نفسه هو الإشارة.
يتم تسجيلها بوسم نوع `[probe]`، منفصل عن الكشف القائم على الحمولة. إذا كان طلب الاستطلاع يحتوي أيضًا على حمولة خبيثة، يتم تسجيل كلاهما بشكل مستقل.
مفعّل افتراضيًا مع أكثر من 50 مسار استطلاع. خصّصه في `config/threat-detection.php`:```php
'probe_tracking' => [
'enabled' => true,
'default_level' => 'medium',
'paths' => [
'/wp-admin' => 'WordPress Admin',
'/wp-admin/*' => 'WordPress Admin',
'/.env' => 'Environment File',
'/phpmyadmin' => 'phpMyAdmin',
'/actuator/*' => 'Spring Actuator',
// Add your own probe paths...
],
],
عطّلها باستخدام THREAT_DETECTION_PROBE_TRACKING=false.
إذا كانت حقول نماذج معيّنة تحتوي بشكل مشروع على HTML أو كلمات مفتاحية لـ SQL أو أكواد (مثل محررات أنظمة إدارة المحتوى CMS، أو حقول إدخال مقاطع الأكواد)، يمكنك استبعادها من الفحص:```php // config/threat-detection.php 'safe_fields' => ['content', 'body', 'html', 'description', 'code'],
الحقول المدرجة هنا تُستبعد من معاملات الاستعلام ومن جسم الطلب - سواء كان مشفّرًا كنموذج (`form-encoded`) أو بصيغة JSON (`application/json`) - قبل تنفيذ عملية الكشف. أما الحقول الأخرى الموجودة في نفس الطلب فستظل خاضعة للفحص الكامل.
### المسارات الآمنة (حساسة للمسار، لواجهات JSON المتداخلة)
`safe_fields` يطابق اسم المفتاح **في أي مكان** يظهر فيه. أما بالنسبة لواجهات JSON المتداخلة، فغالبًا ما يكون هذا النطاق واسعًا جدًا - فقد ترغب في استثناء قيمة حقل معيّن دون استثناء ذلك المفتاح في كل مكان. استخدم `safe_paths`، الذي يطابق حسب **المسار** بترميز النقاط ويدعم أحرف البدل الخاصة بـ `fnmatch`:```php
// config/threat-detection.php
'safe_paths' => ['search.query', 'filters.*.value'],
على سبيل المثال، search.query يُستثنى من قيمة {"search": {"query": "..."}} (صندوق بحث يحتوي نصه بشكل مشروع على كلمات مثل SELECT)، بينما حقل query في أي مكان آخر في الطلب لا يزال يُفحص. كل ما لم يُدرج يُفحص تمامًا كما كان من قبل.
التعبير النمطي وحده لا يمكنه التعبير عن كل قيد: أي تسلسل من 12 رقمًا يطابق نمط Aadhaar، لكن رقم Aadhaar الحقيقي يجتاز أيضًا المجموع الاختباري Verhoeff. اربط تسمية نمط (افتراضية أو مخصصة) بأداة تحقق مسماة، ولا يُحتسب إصابة التعبير النمطي كاكتشاف إلا عندما يجتازها قيمة واحدة مطابقة على الأقل:```php // config/threat-detection.php 'pattern_validators' => [ 'Aadhaar Number Detected' => 'verhoeff', // shipped default ],
المدققات المتاحة:
| المدقق | المجموع الاختباري | الاستخدام النموذجي |
|------------|----------|-------------|
| `verhoeff` | Verhoeff | أرقام أدهار |
| `luhn` | Luhn | أرقام بطاقات الائتمان/الخصم |
مع التعيين المرفق، لم تعد الطوابع الزمنية وأرقام الطلبات والرموز الشريطية التي يبلغ طولها 12 رقمًا تُسجَّل كبيانات شخصية قابلة للتحديد (PII) — بينما لا تزال أرقام أدهار الحقيقية كذلك. إذا تطابقت عدة قيم واجتاز واحد فقط المجموع الاختباري، فلا يزال الاكتشاف يعمل: الرقم الحقيقي وسط الضوضاء لا يزال تسريبًا.
قم بإقران مدقق بنمطك الخاص لاكتشاف البطاقات المقيدة بالمجموع الاختباري:```php
'custom_patterns' => ['/\b(?:\d[ -]?){13,19}\b/' => 'Card Number Detected'],
'pattern_validators' => ['Card Number Detected' => 'luhn'],
اسم مدقق غير معروف يفشل بشكل مفتوح — يُحتسب التطابق دون تحقق ويُسجَّل تحذير مرة واحدة — لذا لا يمكن لخطأ إملائي أن يعطّل نمط اكتشاف بصمت. الإعدادات المنشورة قبل هذه الميزة ببساطة لا تحتوي على المفتاح وتحتفظ بسلوكها الحالي تمامًا.
كان اكتشاف البيانات الحساسة يعني تخزينها. نموذج ملف شخصي يحمل رقم هاتف محمول ورقم PAN وحسابًا بنكيًا كان سيفعّل ثلاثة أنماط PII، وكل صف من الصفوف الثلاثة المكتوبة كان يحتفظ بجسم الطلب كاملًا حرفيًا — محتفظًا به طوال فترة الاحتفاظ الكاملة، وقابلًا للقراءة من قبل أي شخص لديه وصول إلى لوحة التحكم أو قاعدة البيانات. قيمة في سلسلة استعلام كانت تصل أيضًا إلى عمود url. أصبح المكتشف نسخة ثانية مركّزة من الشيء نفسه الذي يحذرك منه.
مفعّل افتراضيًا منذ الإصدار v1.7.0. عندما يُفعَّل نمط مدرج تسميته، تُقنَّع القيمة التي طابقها في الحمولة المخزنة وفي الرابط:``` BODY: {"name":"Jane Doe","mobile":"[REDACTED]","pan":"[REDACTED]","bank_account":"[REDACTED]"}
التنبيه، ونقطة النهاية، وأسماء الحقول، وعنوان IP المهاجم كلها تبقى محفوظة - فقط القيمة تُحذف. يعمل التنقيح *بعد* الاكتشاف، لذا لا يتم تفويت أي شيء.```php
// config/threat-detection.php
'redact' => [
'enabled' => env('THREAT_DETECTION_REDACT', true),
'mask' => '[REDACTED]',
'labels' => ['Aadhaar Number Detected', 'PAN Number Detected', /* ... */],
],
Attack payloads are deliberately left intact - an injection string is evidence, not a secret, and masking it would destroy the investigation. Only labels you list are touched.
This does not replace Safe Fields. Those stop a field being scanned; redaction lets you keep scanning and stop storing. Set
THREAT_DETECTION_REDACT=falseif you need full payloads for forensics.
The dashboard and API support configurable auth guards via .env:```env
THREAT_DETECTION_DASHBOARD_GUARD=auth
THREAT_DETECTION_DASHBOARD_GUARD=role THREAT_DETECTION_DASHBOARD_ROLE=admin
THREAT_DETECTION_DASHBOARD_GUARD=ip THREAT_DETECTION_DASHBOARD_IPS=127.0.0.1,10.0.0.0/8
نفس الخيارات متاحة لمسارات API مع `THREAT_DETECTION_API_GUARD`.
عندما يكون `guard=none` (الافتراضي)، تسجّل الحزمة تحذيرًا مرة واحدة يوميًا لتذكيرك بتكوين المصادقة.
الحارس **يفشل بشكل مغلق**: قيمة حارس غير معروفة (مثل خطأ إملائي) تُرفض برمز 403 مع تحذير مسجّل بدلاً من منح الوصول بصمت، و`guard=role` يرفض (مع تحذير) عندما لا يحتوي نموذج المستخدم المُصادَق عليه على طريقة `hasRole()`.
### تعطيل اكتشاف يتطلب أكثر من صلاحية قراءة
وضع علامة على تهديد كإيجابية كاذبة وحذف قاعدة استثناء كلاهما يكتم نوع اكتشاف للجميع، وهو صلاحية مختلفة عن قراءة السجل. يتم فحص هذين النقطتين النهائيتين مقابل حارس منفصل:```env
# Options: none, auth, role, ip. Default: role
THREAT_DETECTION_API_WRITE_GUARD=role
ينطبق ذلك على تلك المسارات فقط، لذا تعمل القراءة ولوحة التحكم تمامًا كما يحدد THREAT_DETECTION_API_GUARD. بدون ذلك، يمكن لأي مستخدم مصادق عليه في تطبيقك إيقاف تشغيل كشف.
إذا لم يكن نموذج المستخدم لديك يحتوي على hasRole()، فاستخدم =auth. لاستعادة السلوك السابق للإصدار 1.7.0 حيث يمكن لأي مستخدم مصادق عليه تعطيل عمليات الكشف، استخدم =none - وسيُصدر threat-detection:doctor تحذيرًا أثناء ضبط ذلك.
ملاحظة لوحة التحكم ↔ API: تجلب لوحة التحكم المدمجة بياناتها من مسارات API باستخدام ملف تعريف ارتباط جلسة المتصفح. إذا كانت مسارات API لديك محمية بـ
auth:sanctum، فقم بتكوين مصادقة Sanctum ذات الحالة/SPA (أو وجّه لوحة التحكم إلى حارس مصادقة بملفات تعريف الارتباط) بحيث يتم تفويض تلك الاستدعاءات AJAX - وإلا ستُعرض لوحة التحكم فارغة.
أضف أنماط التعبير النمطي للكشف الخاصة بك في config/threat-detection.php:```php
'custom_patterns' => [
'/your-regex-here/i' => 'Your Threat Label',
],
**مثال - كشف فحص نقطة نهاية إدارية مخصصة:**```php
'/\/my-admin-panel/i' => 'Custom Admin Panel Probe',
إلى جانب الصيغة النصية التقليدية، يمكن أن تكون قيمة النمط مصفوفة للتحكم الكامل:```php 'custom_patterns' => [ '/\b(?:\d[ -]?){13,19}\b/' => [ 'label' => 'Card Number Detected', // required 'level' => 'high', // low|medium|high — overrides keyword derivation 'contexts' => ['query', 'body'], // query|body|headers — default: all segments 'validator' => 'luhn', // post-match checksum, wins over pattern_validators ], ],
- **`level`** يضبط مستوى التهديد مباشرة بدلاً من اشتقاقه من كلمات `threat_levels` في التسمية.
- **`contexts`** يقيّد الفحص بشرائح طلب محددة — على سبيل المثال، نمط بطاقة يكون منطقياً فقط في الجسم يتوقف عن مطابقة تسلسلات الأرقام في الترويسات.
- **`validator`** يسمّي فحصاً لاحقاً للمطابقة (انظر [مُتحققات ما بعد المطابقة](#post-match-validators-checksum-aware-false-positive-reduction))؛ وله الأولوية على خريطة تسمية `pattern_validators`.
تختلط إدخالات السلاسل والمصفوفات بحرية في نفس الإعداد. الخيارات غير الصحيحة **تفشل بشكل مفتوح** — لا يزال النمط يفحص دون قيود، ويتم تسجيل تحذير — لذا لا يمكن لخطأ في الإعداد أن يعطّل أو يضيّق اكتشافاً بصمت.
> **ملاحظة:** مسارات الفحص الشائعة مثل `/wp-login.php` و `/.env` و `/phpmyadmin` تُعالج الآن تلقائياً بواسطة ميزة [تتبع فحوصات 404](#404-probe-tracking). لا تحتاج إلى أنماط مخصصة لتلك.
يتم تحديد مستوى التهديد لكل نمط تلقائياً بمطابقة الكلمات في التسمية مع إعداد `threat_levels`:```php
'threat_levels' => [
'high' => ['XSS', 'SQL Injection', 'SQL DDL', 'SQL DML', 'SQL File', 'SQL Hex', 'RCE', ..., 'Shellshock', 'Spring4Shell', 'PowerShell', 'CRLF', 'Null Byte', 'SSTI', 'Java', 'LDAP', 'XPath', 'PHP assert', ...],
'medium' => ['Directory Traversal', 'LFI', 'SSRF', 'Sensitive', 'Config', ..., 'Open Redirect', 'LF Injection', 'GraphQL', 'Spring Boot Actuator', ...],
'low' => ['User-Agent', 'JS Redirect', 'SEO Bot', 'Empty', 'Rate', 'Command-line Downloader', 'DNS Rebinding'],
],
إذا كان التصنيف لا يطابق أي كلمة مفتاحية، فإن التهديد يُعتبر افتراضيًا بخطورة منخفضة.
يتم تخطي أنماط التعبير النمطي غير الصالحة تلقائيًا وتسجيلها كتحذيرات - لن تتسبب في تعطل تطبيقك.
للوصول البرمجي إلى بيانات التهديدات خارج البرمجية الوسيطة:```php use JayAnta\ThreatDetection\Facades\ThreatDetection;
// Get attack statistics for a specific IP $stats = ThreatDetection::getIpStatistics('192.168.1.1');
// Detect coordinated attacks (multiple IPs targeting same URL within 15 minutes) $attacks = ThreatDetection::detectCoordinatedAttacks(15, 3);
// Detect attack campaigns (same threat type from 5+ IPs in last 24 hours) $campaigns = ThreatDetection::detectAttackCampaigns(24);
// Get a summary of all correlation data $summary = ThreatDetection::getCorrelationSummary();
// Operator-side decision helpers (see "Acting on the Data") $blocked = ThreatDetection::isBlocklisted('203.0.113.7'); // static denylist, CIDR, whitelist wins $trusted = ThreatDetection::isWhitelisted('10.0.0.5'); $count = ThreatDetection::ddosRequestCount('203.0.113.7'); // requests in the current DDoS window $flooded = ThreatDetection::isDdosThresholdExceeded('203.0.113.7');
---
## الانتقال إلى الإنتاج
الحزمة سلبية بطبيعتها - فهي لا تحظر أو ترفض أو تعدّل أي طلب أبدًا، ويلفّ برنامج الكشف الوسيط جسمه بالكامل في `try/catch`، لذا لا يمكن لفشل الكشف أن يعطّل تطبيقك. تأتي الحزمة بإعدادات افتراضية معقولة ولا تحتاج إلى خدمات خارجية لتعمل. قبل الإطلاق الفعلي، تستحق هذه القائمة المرجعية نظرة:
1. **احمِ لوحة التحكم وواجهة برمجة التطبيقات (API).** كلاهما يضبط افتراضيًا على `guard = none` لتشغيل أولي بدون إعدادات، ويسجّلان تحذيرًا يوميًا أثناء عدم الحماية. قبل الإنتاج، عيّن حارسًا - `THREAT_DETECTION_DASHBOARD_GUARD` و`THREAT_DETECTION_API_GUARD` (`auth` أو `role` أو `ip`). أي قيمة غير معروفة أو حارس `role` على نموذج مستخدم بدون `hasRole()` سيفشل الآن **بشكل مغلق (403)**، لذا لن يكشف خطأ إملائي البيانات بصمت. تعطيل الكشف محكوم بشكل منفصل بواسطة `THREAT_DETECTION_API_WRITE_GUARD`، الذي يضبط افتراضيًا على `role`. انظر [مصادقة لوحة التحكم وواجهة برمجة التطبيقات](#dashboard-and-api-authentication).
2. **شغّل الترحيلات** (`vendor:publish --tag=threat-detection-migrations && migrate`). إعادة النشر آمنة - يتم تخطي الترحيلات المنشورة بالفعل.
3. **اختر وضع الكشف.** `balanced` (الافتراضي) يناسب معظم التطبيقات؛ استخدم `relaxed` للمواقع الغنية بالمحتوى، و`strict` للأسطح عالية الأمان. اضبط باستخدام `content_paths` و`safe_fields` و`min_confidence` - انظر [تقليل النتائج الإيجابية الخاطئة](#reducing-false-positives).
4. **راجع أنماط المعلومات الشخصية الإقليمية / الأنماط المخصصة.** الافتراضيات تركز على الهند (Aadhaar وPAN وIFSC) والأنماط الرقمية الواسعة (مثل الحساب البنكي) يمكن أن تطابق معرّفات رقمية طويلة خارج مسارات المصادقة. استبدل أو قلّص `custom_patterns` لمنطقتك وتطبيقك، وأضف مسارات المحتوى الثقيل إلى `auth_paths` / `content_paths`.
5. **فعّل الاحتفاظ** إذا كنت تتوقع حجمًا كبيرًا: `THREAT_DETECTION_RETENTION=true` (تنظيف تلقائي عبر المجدول). يتطلب أن يكون مجدول Laravel (`schedule:run`) مدفوعًا بـ cron.
6. **إضافات اختيارية، كلها معطلة افتراضيًا:** تنبيهات Slack (`THREAT_DETECTION_NOTIFICATIONS`)، وإثراء الموقع الجغرافي (`php artisan threat-detection:enrich` - الميزة الوحيدة التي تقوم باستدعاء خارجي، إلى خدمة ip-api.com المجانية)، والكتابة في قائمة الانتظار (`THREAT_DETECTION_QUEUE` - فعّلها فقط إذا كنت تشغّل عامل قائمة انتظار بالفعل؛ وإلا تكون الكتابة متزامنة ولا تحتاج إلى Redis).
لا حاجة إلى Redis أو عامل قائمة انتظار أو استدعاءات شبكة صادرة للكشف والتسجيل الأساسيين.
---
## تقليل النتائج الإيجابية الخاطئة
توفر الحزمة أدوات متعددة لتقليل النتائج الإيجابية الخاطئة. استخدم ما يناسب حالتك:
### الحقول والمسارات الآمنة
استبعد حقلًا من الفحص تمامًا، إما بالاسم في كل مكان (`safe_fields`) أو بمسار تدوين النقاط لـ JSON المتداخل (`safe_paths`). أبسط نهج، والأكثر حدة - يتم تخطي الحقل، لذا لا يعمل أي كشف عليه على الإطلاق.
التفاصيل الكاملة والأمثلة: [الحقول الآمنة](#safe-fields-false-positive-reduction).
### قمع مسار المحتوى
إذا كان لديك محررو CMS أو نماذج منشورات مدونة أو أقسام تعليقات حيث يرسل المستخدمون محتوى غنيًا، فإن تلك المسارات غالبًا ما تثير نتائج إيجابية خاطئة (مثل منشور مدونة يحتوي على أمثلة كود `<script>`). أضف تلك المسارات لقمع التنبيهات المنخفضة/المتوسطة:```php
// config/threat-detection.php
'content_paths' => [
'admin/posts/*',
'admin/pages/*',
'blog/*/edit',
'comments',
],
في هذه المسارات، يتم تسجيل التهديدات عالية الخطورة فقط.
انقر على زر FP على أي تهديد في لوحة التحكم لتمييزه كنتيجة إيجابية خاطئة. يؤدي هذا إلى:
is_false_positive = trueإدارة قواعد الاستثناء عبر API:```bash GET /api/threat-detection/exclusion-rules DELETE /api/threat-detection/exclusion-rules/{id}
### تسجيل الثقة
يحصل كل تهديد على درجة ثقة (0-100) بناءً على:
- عدد مرات تطابق الأنماط في نفس الطلب
- خطورة النمط المطابق
- مكان العثور على النمط (سلسلة الاستعلام > الترويسات > النص)
- ما إذا كان وكيل المستخدم يطابق أداة هجوم معروفة
- وضع الكشف الحالي
لا يتم تسجيل التهديدات التي تقل عن عتبة الثقة الخاصة بوضع الكشف لديك (انظر [أوضاع الكشف](#detection-modes)).
---
## أنواع الهجمات المكتشفة
| الفئة | أمثلة |
|----------|---------|
| **حقن SQL** | UNION، boolean، time-based، ترميز CHAR، DDL (DROP/ALTER/CREATE)، DML (INSERT/UPDATE/DELETE)، عمليات الملفات (INTO OUTFILE، LOAD_FILE)، تعداد ORDER BY، سلاسل hex، UNHEX |
| **حقن NoSQL** | عوامل تشغيل MongoDB $ne، $gt، $regex، $where |
| **XSS** | وسوم السكربت، معالجات أحداث SVG (`<svg onload=`)، معالجات أحداث HTML (`<body onload=`، `<img onerror=`)، تعبيرات CSS، URIs جافاسكريبت، معالجة DOM |
| **تنفيذ الأكواد** | دوال شل RCE، إلغاء تسلسل PHP، إلغاء تسلسل Java (base64 + بايتات سحرية hex)، حقن القوالب (Blade، JSP، ASP، Jinja2، Velocity)، eval()، فك ترميز base64، assert() في PHP، create_function()، preg_replace /e |
| **SSTI** | فحوصات رياضية (`{{7*7}}`)، استيراد/إعداد Jinja2، قوالب Velocity، لغة التعبير |
| **حقن الأوامر** | لينكس (دوال الشل، سلاسل الأوامر، curl، wget، nc)، ويندوز (cmd.exe، PowerShell، wscript، cscript، net user) |
| **الوصول إلى الملفات** | اجتياز الدلائل، بروتوكولات LFI/RFI، فحوصات الملفات الحساسة (.env، .git، composer.json) |
| **SSRF** | المضيف المحلي (127.0.0.1، 0.0.0.0، ::1)، بيانات AWS/GCP الوصفية، عناوين IP خاصة، مضيف محلي بترميز hex/عشري، إعادة ربط DNS (xip.io، nip.io، sslip.io) |
| **حقن LDAP** | التلاعب بمرشحات LDAP، حقن OR |
| **حقن XPath** | محددات السمات، دوال XPath (contains، substring) |
| **حقن CRLF / الترويسات** | CRLF بترميز URL (`%0d%0a`)، حقن LF، حقن البايت الفارغ |
| **هجمات البروتوكول** | تهريب طلبات HTTP (CL+TE)، حقن SSI |
| **استغلالات CVE** | Shellshock (CVE-2014-6271)، Spring4Shell (CVE-2022-22965)، PHPUnit RCE (CVE-2017-9841)، Drupalgeddon، Log4Shell |
| **تتبع الفحوصات** | ووردبريس (`/wp-admin`، `/wp-login.php`)، ملفات الإعداد (`/.env`، `/.git`)، أدوات قواعد البيانات (`/phpmyadmin`)، فحوصات التقنيات (`.asp`، `.jsp`)، Spring actuator، توثيق Swagger/API - أكثر من 50 مسارًا |
| **الماسحات الضوئية** | SQLMap، Nikto، Nmap، Burp Suite، FeroxBuster، FFUF، XSStrike، Dalfox، Netsparker، Qualys، Nuclei، وأكثر من 20 أداة أخرى (53 إجمالاً) |
| **كواشط الذكاء الاصطناعي** | GPTBot، ClaudeBot، ChatGPT، ByteSpider، Cohere، Common Crawl |
| **المتصفحات بدون واجهة** | HeadlessChrome، PhantomJS، Selenium، Puppeteer، Playwright |
| **الروبوتات** | نصوص بايثون، عملاء HTTP بلغة Go، cURL، wget، AhrefsBot، SEMRushBot، وكلاء مستخدم فارغون |
| **المصادقة** | كشف القوة الغاشمة، تسرب الرموز، كشف كلمات المرور، كشف معرفات الجلسات |
| **DDoS** | كشف الطلبات المفرطة القائمة على المعدل |
| **التهرب** | إدراج تعليقات SQL، ترميز URL مزدوج، ترميز كيانات HTML، هروب Unicode، IIS Unicode، هروب hex |
| **أخرى** | استعلام GraphQL، تلوث النموذج الأولي، إعادة التوجيه المفتوحة، XXE، القشرة الويب، تعدين العملات المشفرة، كشف PII |
---
## تشغيل مجموعة الاختبارات```bash
composer test
تتضمن الحزمة 335 اختبارًا (856 تأكيدًا) تغطي أنماط الكشف، وسلوك البرمجيات الوسيطة، ونقاط نهاية API، وتقييم الثقة، وقواعد الاستبعاد، وكشف DDoS، ومقاومة التهرب، وأنماط CVE، وحقن LDAP/XPath/SSTI، وكشف الروبوتات/الماسحات الضوئية، وتتبع الفحوصات، وأوامر التصدير، ومصادقة لوحة المعلومات، والحقول الآمنة، وتحسينات الأداء، والتحقق الكامل من دورة HTTP إلى قاعدة البيانات.
رخصة MIT. راجع LICENSE للحصول على التفاصيل.
المساهمات مرحب بها! يرجى تقديم طلب سحب (Pull Request).
Total Threats | عدد التهديدات الكلي |
|---|
Critical | حرج |
High | مرتفع |
Medium | متوسط |
Low | منخفض |
Top IPs | أهم عناوين IP |
strict، balanced (الافتراضي)، وrelaxed - حساسية قابلة للضبطapi.guard