rafalmasiarek/threat-detector

Heuristic, modular threat detection (signal-only) with weighted float scoring, predefined thresholds, and PSR-15 middleware for PSR-7 apps.

v1.0.0 2025-09-07 21:35 UTC

This package is auto-updated.

Last update: 2025-09-07 23:09:08 UTC


README

Latest Version License PHP

Heuristic, modular threat detection (signal-only) with weighted float scoring, predefined thresholds, and PSR-15 middleware for PSR-7 applications.

⚠️ This library is a signal generator. It does not replace proper validation/sanitization/escaping, CSP, prepared statements, etc.

Features

  • 🧩 Modular scanners β€” each category (XSS, SQLi, SSRF, …) in a separate class.
  • βš–οΈ Weighted float scoring β€” per-category weights; combine multiple signals.
  • 🎚️ Predefined thresholds β€” LOW, MEDIUM, HIGH (or custom floats).
  • 🧡 PSR-15 middleware β€” scan query, body, headers, cookies; annotate request; optional header X-Threat-Suspect.
  • πŸ“ phpDocs & comments β€” production-friendly code with clear docs.
  • βœ… Unit tests β€” a couple of quick checks to get you started.
  • πŸ“‚ Examples β€” basic HTML form + PSR-15 middleware demo.

Requirements

  • PHP 8.1+
  • ext-mbstring

Installation

Using Composer:

composer require rafalmasiarek/threat-detector

If you are using this repository locally (path repo):

composer config repositories.threat-detector path ./threat-detector
composer require rafalmasiarek/threat-detector:dev-main

Quick Start (Core)

use rafalmasiarek\Threat\Core\ThreatDetector;
use rafalmasiarek\Threat\Core\ScoringPolicy;
use rafalmasiarek\Threat\Core\Thresholds;

// Create a policy with default weights and MEDIUM threshold
$policy = ScoringPolicy::withDefaults()
    ->withThreshold(Thresholds::MEDIUM)  // or 'LOW' | 'HIGH' | 3.5 (float)
    ->withWeight('SQLI', 2.25);          // optional: override category weights

$detector = ThreatDetector::default($policy);

// Scan a string
$input = "<script>alert(1)</script>";
$result = $detector->scanString($input);

var_dump($result->suspect); // bool
var_dump($result->score);   // float
var_dump($result->hits);    // array{category => list<string>}
var_dump($result->norm);    // normalized input

Example output:

bool(true)
float(3)
array(1) {
  ["XSS"]=>
  array(2) {
    [0]=> string(10) "TAG_SCRIPT"
    [1]=> string(9)  "HTML_TAGS"
  }
}
string(23) "<script>alert(1)</script>"

Quick Start (PSR-15 Middleware)

use rafalmasiarek\Threat\Middleware\ThreatDetectMiddleware;

$middleware = new ThreatDetectMiddleware([
    'threshold'    => 'MEDIUM',          // 'LOW' | 'MEDIUM' | 'HIGH' | float
    'weights'      => ['SQLI' => 2.1],   // optional overrides
    'scan_query'   => true,
    'scan_body'    => true,
    'scan_headers' => false,             // true or array of headers to scan
    'scan_cookies' => false,
    'attribute'    => 'threat.result',   // request attribute name
    'set_header'   => true,              // add X-Threat-Suspect: 1 when suspect
]);

// Add to your PSR-15 stack (Slim/Mezzio/etc.)
$result = $request->getAttribute('threat.result'); 

Example result:

[
  'suspect' => true,
  'score'   => 3.5,
  'hits'    => ['XSS' => ['TAG_SCRIPT','HTML_TAGS']],
]

Scoring

  • Weights: per category (e.g., SQLI=2.0, CMD_INJECTION=2.5, CRLF=1.0).
  • Score formula:
    score = Ξ£ ( weight(category) Γ— unique_hits(category) )
    
  • Threshold: request is suspect when score β‰₯ threshold.

Predefined thresholds

Name Value Sensitivity
LOW 1.0 Very sensitive
MEDIUM 2.5 Balanced (default)
HIGH 5.0 Strict

Examples

  • <script>alert(1)</script>
    Hits: XSS=[TAG_SCRIPT, HTML_TAGS]
    Score: 1.5 Γ— 2 = 3.0 β†’ suspect at MEDIUM

  • UNION SELECT password FROM users
    Hits: SQLI=[UNION_SELECT]
    Score: 2.0 Γ— 1 = 2.0 β†’ not suspect at MEDIUM, suspect at LOW

Categories & Scanners

  • XSS β€” inline event handlers, <script>, javascript: URIs.
  • SQLI β€” UNION SELECT, SLEEP(), INFORMATION_SCHEMA, etc.
  • CMD_INJECTION β€” subshells, ;, &&, wget/curl, redirects.
  • PATH_TRAVERSAL β€” ../, URL-encoded traversal, file://, wrappers.
  • CRLF β€” header injection sequences.
  • SSRF β€” URLs to localhost, 127.0.0.1, RFC1918 ranges.
  • XXE β€” <!DOCTYPE>, <!ENTITY>, external SYSTEM.
  • NOSQL β€” Mongo-like operators $where, $regex.
  • LDAP β€” wildcards, null bytes.
  • SERIALIZATION β€” PHP serialized payload patterns.

Integration Ideas

  • Add to Slim/Mezzio pipeline as PSR-15 middleware.
  • Run against form input before sending mail (contact forms).
  • Log suspect inputs into a security audit trail.
  • Flag suspicious requests in rate-limiting / WAF logic.

Tests & Examples

  • PHPUnit tests included (tests/):
    • TruePositiveDetectionsTest.php
    • FalsePositiveHeuristicsTest.php
  • Example apps in examples/:
    • basic/ (HTML form demo)
    • psr15/ (middleware demo)

Run tests:

./vendor/bin/phpunit --colors=always

Security Notice

This library generates signals only.
Always combine with:

  • Prepared statements for SQL queries
  • Proper HTML escaping and CSP
  • Strong input validation

Folder Structure

src/
  Contracts/ScannerInterface.php
  Core/{ThreatDetector.php, ThreatResult.php, ScoringPolicy.php, Thresholds.php}
  Scanner/{XssScanner.php, SqliScanner.php, CmdInjectionScanner.php, PathTraversalScanner.php, CrlfScanner.php, SsrfScanner.php, XxeScanner.php, NoSqlScanner.php, LdapScanner.php, SerializationScanner.php}
  Middleware/ThreatDetectMiddleware.php
tests/
  ModularThreatDetectorTest.php
examples/
  basic/
  psr15/

License

MIT