Smart-IDS
5-layer hybrid Intrusion Detection System for WordPress (ML + LLM). PFE ISIMa.
by Nasrallah Jomaa & Ahmed Garma · github.com/nasrallahjomaa/smart-ids · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/nasrallahjomaa/smart-ids/archive/refs/heads/main.zipReadme
Smart-IDS
A 5-layer hybrid Intrusion Detection System for WordPress — combining pre-boot PHP interception, file-integrity monitoring, a WAF, deception, and a machine-learning engine with an LLM tie-breaker to catch obfuscated / zero-day PHP webshells that signature-based scanners miss.
Built as an end-of-studies project (PFE) at ISIMa — Institut Supérieur d'Informatique de Mahdia, filière ingénierie des réseaux et systèmes. Defended June 2026 — mention très bien. Authors: Nasrallah Jomaa & Ahmed Garma · Encadrante: Najoua Achoura.
Why
Most WordPress scanners (Wordfence, etc.) rely on signatures. An attacker who
obfuscates a webshell (base64, eval, dynamic dispatch) walks past them.
Smart-IDS layers behavioural, integrity, and ML-based detection so that a
file that looks novel but behaves like a shell still gets caught — and is
held before WordPress even boots.
Architecture — the 5 layers
| Layer | Name | Role |
|---|---|---|
| 0 | Interceptor | auto_prepend_file runs before WordPress boots. Scores every request from a flat-file blocklist / verdict cache; high-risk requests are held synchronously and never reach the app. |
| 1 | FIM + WAF + Brute-force | File-integrity monitoring (core-drift detection), a request WAF (SQLi/XSS/LFI/path-traversal), and login rate-limiting with IP lockout. |
| 2 | Deception | Honeytoken trap file, canary decoy credentials, file immutability (chattr +i), and C2 surveillance (observe-only; admin-decided iptables block — no hack-back). |
| 3 | ML engine + LLM | A Python (Flask) service classifies suspicious files (Random Forest + char n-gram ensemble over 58 engineered features); an LLM acts as a tie-breaker in the uncertain zone. |
| 4 | Dashboard + REST | A WordPress admin dashboard with live activity, forensic drawers (explainable scores), traffic monitor, and a REST API. |
How detection flows
request ─▶ Layer 0 (pre-boot scoring) ─▶ hold / pass
file event ─▶ ML engine ──┐
├─▶ Decision engine (mean & gap of RF / n-gram)
LLM tie-breaker ──────────┘ │
├─ BLOCK
├─ QUARANTINE + LLM review
└─ PASS
The decision engine is mean-based: it combines the Random Forest score (RF)
and the n-gram score (NG) into mean = (RF+NG)/2 and gap = |RF−NG|, then
applies a fixed ladder (whitelist → dangerous-chain → high-confidence block →
quarantine-with-LLM → pass). Protected paths (wp-config.php, the plugin's own
files, …) are never auto-quarantined.
The ML model
- 58 engineered features: static, AST-derived, entropy, plus WordPress-domain
signals (top features: a hand-crafted weighted-risk composite,
dangerous-chain count,
evalcount,base64_decodecount). - Two models: Random Forest + char 3–4-gram TF-IDF → LogisticRegression,
combined as
0.6·RF + 0.4·NGat threshold 0.5. - Holdout metrics: accuracy 99.5%, precision 78.6%, recall 96.7%, F1 86.7%, false-positive rate 0.41%. (Reported numbers are pure-ML — whitelist, dangerous chains, and the LLM are excluded from the evaluation.)
The training corpus (real malware samples, ~438 MB) is not shipped here. The trained models (
ml-engine/*.pkl) are committed so the plugin works out of the box. To retrain, seeml-engine/RETRAIN.md.
Quick start (Docker)
git clone https://github.com/NasrallahJomaa/smart-ids.git
cd smart-ids
# 1. ML engine secret (shared with the plugin)
cp ml-engine/.env.example ml-engine/.env
echo "SMART_IDS_API_KEY=$(openssl rand -hex 16)" > ml-engine/.env
# 2. Stack
cp docker-compose.example.yml docker-compose.yml # then edit creds / paths
docker compose up -d
- WordPress: http://localhost:8080 · phpMyAdmin: http://localhost:8081
- In WP admin → Smart-IDS → Settings: paste the same
SMART_IDS_API_KEYfor the ML engine, and your LLM provider key (stored encrypted).
Configuration
- API keys are entered in the plugin's Settings page, not in code. The LLM
key is stored encrypted (
smart_ids_llm_api_key_encviawp_salt). - Brute-force / honeytoken skip private IPs by default
(
smart_ids_bf_skip_private) so you don't lock yourself out onlocalhost— disable the skip to test the protections.
Testing
Inert test scripts live in bin/ — run them against your own test
install only:
bin/test-layer0.sh # pre-boot interception
bin/test-waf.sh # SQLi / XSS / path-traversal blocking
bin/test-upload-guard.sh # webshell-in-/uploads detection
bin/test-immutability.sh # chattr-based file protection
Project layout
smart-ids.php Plugin bootstrap (WP header, hooks)
smart-ids-prepend.php Layer 0 interceptor (auto_prepend_file)
includes/ Layer classes (firewall, fim, brute-force, deception, decision, …)
admin/ Dashboard UI (views, partials, assets)
ml-engine/ Python Flask service: api.py, features.py, train_model.py, models (*.pkl)
docker/ wordpress.Dockerfile
bin/ FIM cron + inert test scripts
Disclaimer
Smart-IDS is a defensive security research tool. Use it only on systems you own or are authorized to test. See SECURITY.md.
License
GPL-2.0-or-later © 2026 Nasrallah Jomaa & Ahmed Garma.