Every figure below traces to a specific test set, live-traffic run, or independent payload corpus described in the repo's docs/. Where a number changed between model versions, we cite the current one and note the history.
Held-out test set, n=59,947 requests, current shipped model. cmdi is the hardest class to separate — see limitation #1 for why.
| Class | Precision | Recall | F1 | Support |
|---|---|---|---|---|
| benign | 0.9980 | 0.9992 | 0.9986 | 18,042 |
| cmdi | 0.8749 | 0.9170 | 0.8954 | 831 |
| path_traversal | 0.9694 | 0.9648 | 0.9671 | 2,526 |
| sqli | 0.9953 | 0.9956 | 0.9955 | 34,085 |
| xss | 0.9911 | 0.9778 | 0.9844 | 4,463 |
cmdi F1 has moved across retrains as the corpus grew: 0.8954 → 0.902 with SMOTE tuning (a ceiling — see limitations) → 0.895 on the current minimal-context retrain (rf_v10/if_v9), the figure the CLI's attacks inspect cmdi reports as the locked test-set number.
100 payloads per class, run against a live Express app with the shipped rf_v10/if_v9 worker-pool build.
An earlier suite (rf_v3/if_v2, 100 payloads/class) measured sqli 99–100%, xss 94.0%, path_traversal 100%, cmdi 95.0%, with a 2.0% benign false-positive rate — included here because the two runs used different payload sets and both are honest snapshots of their model version.
This is the one metric where the project's own target isn't met, and we say so plainly rather than burying it.
~0.1–15ms depending on environment. In a real Docker + Postgres deployment — the most representative environment — p95 overhead lands around 7–9ms (baseline ~4–5ms → with logSguarDian ~12–14ms).
+70% to +340% depending on build and environment, against the project's own ≤10% relative target. Relative-percentage overhead is mathematically punishing against a near-instant baseline: Δp95_relative = ε / p95_baseline diverges as the baseline approaches zero for any nonzero ε — a structural property of the metric, not evidence of a slow implementation, but the gate is not met and we're not going to dress that up.
| Measurement | p50 | p95 | p99 |
|---|---|---|---|
| Feature extractor (mixed traffic, main thread) | — | 0.0082ms | — |
| ONNX worker round-trip | 0.823ms | 1.044ms | 1.130ms |
| Bare-Node middleware (Windows/WSL2, 50 arr/s) | — | +0ms vs baseline | — |
| Docker + Postgres, full hybrid (realistic deployment) | — | ~7–9ms overhead | — |
Stack: Nginx + ModSecurity v3 + OWASP CRS at Paranoia Level 1 — the realistic default for a team without dedicated WAF-tuning staff, not artificially weakened — reverse-proxying to an Express + logSguarDian app backed by Postgres. Corpus: 590 payloads from SecLists (seed=42, deduplicated): 77 sqli, 113 xss, 200 of 881 unique path_traversal, 200 of 8,262 unique cmdi.
| Category | No protection | logSguarDian only | WAF only (PL1) | Layered |
|---|---|---|---|---|
| sqli | 0/77 | 76/77 | 66/77 | 77/77 |
| xss | 0/113 | 110/113 | 110/113 | 113/113 |
| path_traversal | 0/200 | 197/200 | 174/200 | 197/200 |
| cmdi | 0/200 | 200/200 | 200/200 | 200/200 |
| Overall | 0/590 | 583/590 | 550/590 | 587/590 |
Of the 40 attacks CRS (PL1) missed, attributing Config 3b's blocks by response signature shows 37 were independently caught by logSguarDian after passing the WAF. Only 3 payloads passed both layers, and none are real vulnerabilities against the target app — they were non-functional generic LFI strings with no ../ sequence.
Against the same app with no WAF and no middleware, all 6 tested attack vectors fully compromised it: SQLi auth bypass via ' OR '1'='1' -- (full admin session), SQLi UNION exfiltration (plaintext credential dump including admin/admin123), stored XSS in two fields executing unescaped, path traversal reading /etc/passwd, and command injection running as root inside the container — unrestricted, not a scoped service account.
A documented proof-of-concept in the target app's own vulnerability notes had a bug (wrong SQL column count) that was found and corrected during testing. Every result was captured against a live running instance and cross-checked against logSguarDian's own event log. CRS PL1 was chosen deliberately as the realistic default for the target audience, not weakened to flatter the comparison.
Licenses were audited per-source. Two sources have no clear license from the original publisher — logSguarDian does not redistribute their raw data, only derived 73-feature vectors, and we're stating that plainly rather than glossing over it.
| Source | License | Records | Classes |
|---|---|---|---|
| SR-BH 2020 / CAPEC multilabel | CC0-1.0 | 289,287 | sqli, xss, path_traversal, cmdi |
| modsec-learn | MIT | 539,074 | sqli, benign |
| OWASP ModSec honeypot logs | CC BY 4.0 | 56,399 | sqli, xss, path_traversal, cmdi |
| Payloads.csv (Shahane) | CC BY 4.0 | 21,624 | xss, benign |
| payload_full.csv (Thakur) | MIT | 31,067 | all 5 (cmdi scarce, 89 rows) |
| XSS_dataset.csv (Shah) | Unspecified — no raw redistribution | 13,570 | xss, benign |
| command injection.csv (Pawase) | Unspecified — no raw redistribution | 2,105 | cmdi, benign |
| omurugur Path Traversal Payload List | MIT | 43,137 | path_traversal |
| russellmitchell (AIT-LDSv2) | CC-BY-NC-SA-4.0 | excluded | role labels ≠ attack type; NC clause |
v9 added 2,470 real command-injection payloads from SecLists' command-injection-commix.txt and PayloadsAllTheThings, verified at 0% near-duplicate overlap (MinHash, threshold 0.70) with the existing corpus — a 44.5% growth in the cmdi class that measurably improved detection (see limitation #1).
Generalization is bounded to the styles in this corpus. A leave-one-source-out test found 0 of 9 sources reach macro F1 ≥ 0.80 when held out entirely; only command_injection clears 0.60 (0.7762). A genuinely novel attack or benign style — one unlike anything in these 9 sources — should be expected to degrade detection meaningfully. Full breakdown in limitation #4.