feat(Production): Complete production deployment infrastructure

- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -5,15 +5,25 @@ declare(strict_types=1);
namespace App\Framework\Waf\MachineLearning\Extractors;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\MachineLearning\Core\FeatureExtractorMetadata;
use App\Framework\MachineLearning\Core\FeatureExtractorPerformance;
use App\Framework\MachineLearning\ValueObjects\Feature;
use App\Framework\MachineLearning\ValueObjects\FeatureType;
use App\Framework\Waf\Analysis\ValueObjects\RequestAnalysisData;
use App\Framework\Waf\MachineLearning\BehaviorType;
use App\Framework\Waf\MachineLearning\FeatureExtractorInterface;
use App\Framework\Waf\MachineLearning\ValueObjects\BehaviorFeature;
use App\Framework\Waf\MachineLearning\WafFeatureExtractor;
/**
* Extracts request frequency and rate-based behavioral features
*
* Uses atomic interface composition pattern (NO extends):
* - WafFeatureExtractor: Domain-specific feature extraction
* - FeatureExtractorMetadata: Metadata and configuration
* - FeatureExtractorPerformance: Performance characteristics
*/
final class FrequencyFeatureExtractor implements FeatureExtractorInterface
final class FrequencyFeatureExtractor implements
WafFeatureExtractor,
FeatureExtractorMetadata,
FeatureExtractorPerformance
{
public function __construct(
private readonly bool $enabled = true,
@@ -24,9 +34,9 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
) {
}
public function getBehaviorType(): BehaviorType
public function getFeatureType(): FeatureType
{
return BehaviorType::REQUEST_FREQUENCY;
return FeatureType::FREQUENCY;
}
public function canExtract(RequestAnalysisData $requestData): bool
@@ -78,12 +88,12 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract basic request rate
*/
private function extractRequestRate(array $requests, int $windowSeconds): BehaviorFeature
private function extractRequestRate(array $requests, int $windowSeconds): Feature
{
$count = count($requests);
$rate = $windowSeconds > 0 ? $count / $windowSeconds : 0.0;
return BehaviorFeature::frequency(
return Feature::frequency(
name: "request_rate_{$windowSeconds}s",
count: $count,
timeWindow: $windowSeconds
@@ -93,11 +103,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract burst detection rate
*/
private function extractBurstRate(array $requests, int $windowSeconds): BehaviorFeature
private function extractBurstRate(array $requests, int $windowSeconds): Feature
{
if (count($requests) < 2) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: "burst_rate_{$windowSeconds}s",
value: 0.0,
unit: 'requests/second'
@@ -124,8 +134,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$maxRate = max($maxRate, $rate);
}
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: "burst_rate_{$windowSeconds}s",
value: $maxRate,
unit: 'requests/second'
@@ -135,7 +145,7 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract sustained rate (longer window)
*/
private function extractSustainedRate(array $requests, int $windowSeconds): BehaviorFeature
private function extractSustainedRate(array $requests, int $windowSeconds): Feature
{
$count = count($requests);
@@ -149,8 +159,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$sustainedCount = count($sustainedRequests);
$rate = $windowSeconds > 0 ? $sustainedCount / $windowSeconds : 0.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: "sustained_rate_{$windowSeconds}s",
value: $rate,
unit: 'requests/second'
@@ -160,11 +170,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract inter-arrival time variance
*/
private function extractInterArrivalVariance(array $requests): BehaviorFeature
private function extractInterArrivalVariance(array $requests): Feature
{
if (count($requests) < 3) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'inter_arrival_variance',
value: 0.0,
unit: 'seconds²'
@@ -180,8 +190,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$interArrivals[] = $requests[$i] - $requests[$i - 1];
}
return BehaviorFeature::statistical(
type: $this->getBehaviorType(),
return Feature::statistical(
type: $this->getFeatureType(),
name: 'inter_arrival_variance',
values: $interArrivals,
statistic: 'variance'
@@ -191,11 +201,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract request spacing regularity
*/
private function extractRequestSpacing(array $requests): BehaviorFeature
private function extractRequestSpacing(array $requests): Feature
{
if (count($requests) < 3) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'request_spacing_regularity',
value: 0.0,
unit: 'coefficient'
@@ -211,8 +221,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
}
$mean = array_sum($interArrivals) / count($interArrivals);
$variance = BehaviorFeature::statistical(
type: $this->getBehaviorType(),
$variance = Feature::statistical(
type: $this->getFeatureType(),
name: 'temp_variance',
values: $interArrivals,
statistic: 'variance'
@@ -221,8 +231,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
// Coefficient of variation (lower = more regular)
$regularity = $mean > 0 ? sqrt($variance) / $mean : 1.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'request_spacing_regularity',
value: 1.0 / (1.0 + $regularity), // Normalize: 1 = perfectly regular, 0 = very irregular
unit: 'regularity_score'
@@ -232,11 +242,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract periodicity score using autocorrelation
*/
private function extractPeriodicityScore(array $requests): BehaviorFeature
private function extractPeriodicityScore(array $requests): Feature
{
if (count($requests) < 10) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'periodicity_score',
value: 0.0,
unit: 'correlation'
@@ -251,8 +261,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$duration = $maxTime - $minTime;
if ($duration <= 0) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'periodicity_score',
value: 0.0,
unit: 'correlation'
@@ -279,8 +289,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$maxCorrelation = max($maxCorrelation, abs($correlation));
}
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'periodicity_score',
value: $maxCorrelation,
unit: 'correlation'
@@ -290,11 +300,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract time of day pattern
*/
private function extractTimeOfDayPattern(array $requests): BehaviorFeature
private function extractTimeOfDayPattern(array $requests): Feature
{
if (empty($requests)) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'time_of_day_entropy',
value: 0.0,
unit: 'bits'
@@ -309,8 +319,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$hourDistribution[$hour]++;
}
return BehaviorFeature::entropy(
type: $this->getBehaviorType(),
return Feature::entropy(
type: $this->getFeatureType(),
name: 'time_of_day_entropy',
distribution: $hourDistribution
);
@@ -319,11 +329,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract weekday pattern
*/
private function extractWeekdayPattern(array $requests): BehaviorFeature
private function extractWeekdayPattern(array $requests): Feature
{
if (empty($requests)) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'weekday_entropy',
value: 0.0,
unit: 'bits'
@@ -338,8 +348,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$dayDistribution[$day]++;
}
return BehaviorFeature::entropy(
type: $this->getBehaviorType(),
return Feature::entropy(
type: $this->getFeatureType(),
name: 'weekday_entropy',
distribution: $dayDistribution
);
@@ -348,11 +358,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract frequency distribution entropy
*/
private function extractFrequencyEntropy(array $requests): BehaviorFeature
private function extractFrequencyEntropy(array $requests): Feature
{
if (count($requests) < 5) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'frequency_entropy',
value: 0.0,
unit: 'bits'
@@ -369,8 +379,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$buckets[$bucket] = ($buckets[$bucket] ?? 0) + 1;
}
return BehaviorFeature::entropy(
type: $this->getBehaviorType(),
return Feature::entropy(
type: $this->getFeatureType(),
name: 'frequency_entropy',
distribution: array_values($buckets)
);
@@ -379,11 +389,11 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
/**
* Extract burstiness measure
*/
private function extractBurstiness(array $requests): BehaviorFeature
private function extractBurstiness(array $requests): Feature
{
if (count($requests) < 5) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'burstiness',
value: 0.0,
unit: 'burstiness_coefficient'
@@ -399,8 +409,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
}
$mean = array_sum($interArrivals) / count($interArrivals);
$variance = BehaviorFeature::statistical(
type: $this->getBehaviorType(),
$variance = Feature::statistical(
type: $this->getFeatureType(),
name: 'temp_variance',
values: $interArrivals,
statistic: 'variance'
@@ -411,8 +421,8 @@ final class FrequencyFeatureExtractor implements FeatureExtractorInterface
$stdDev = sqrt($variance);
$burstiness = ($stdDev + $mean) > 0 ? ($stdDev - $mean) / ($stdDev + $mean) : 0.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'burstiness',
value: $burstiness,
unit: 'burstiness_coefficient'

View File

@@ -4,15 +4,25 @@ declare(strict_types=1);
namespace App\Framework\Waf\MachineLearning\Extractors;
use App\Framework\MachineLearning\Core\FeatureExtractorMetadata;
use App\Framework\MachineLearning\Core\FeatureExtractorPerformance;
use App\Framework\MachineLearning\ValueObjects\Feature;
use App\Framework\MachineLearning\ValueObjects\FeatureType;
use App\Framework\Waf\Analysis\ValueObjects\RequestAnalysisData;
use App\Framework\Waf\MachineLearning\BehaviorType;
use App\Framework\Waf\MachineLearning\FeatureExtractorInterface;
use App\Framework\Waf\MachineLearning\ValueObjects\BehaviorFeature;
use App\Framework\Waf\MachineLearning\WafFeatureExtractor;
/**
* Extracts behavioral patterns from URL paths, parameters, and request structure
*
* Uses atomic interface composition pattern (NO extends):
* - WafFeatureExtractor: Domain-specific feature extraction
* - FeatureExtractorMetadata: Metadata and configuration
* - FeatureExtractorPerformance: Performance characteristics
*/
final class PatternFeatureExtractor implements FeatureExtractorInterface
final class PatternFeatureExtractor implements
WafFeatureExtractor,
FeatureExtractorMetadata,
FeatureExtractorPerformance
{
public function __construct(
private readonly bool $enabled = true,
@@ -24,9 +34,9 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
) {
}
public function getBehaviorType(): BehaviorType
public function getFeatureType(): FeatureType
{
return BehaviorType::PATH_PATTERNS;
return FeatureType::STRUCTURAL_PATTERN;
}
public function canExtract(RequestAnalysisData $requestData): bool
@@ -149,13 +159,13 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path depth (number of segments)
*/
private function extractPathDepth(string $path): BehaviorFeature
private function extractPathDepth(string $path): Feature
{
$segments = array_filter(explode('/', trim($path, '/')));
$depth = count($segments);
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_depth',
value: $depth,
unit: 'segments'
@@ -165,7 +175,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path complexity score
*/
private function extractPathComplexity(string $path): BehaviorFeature
private function extractPathComplexity(string $path): Feature
{
$segments = array_filter(explode('/', trim($path, '/')));
@@ -184,8 +194,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$complexity += $specialChars * 0.5;
}
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_complexity',
value: $complexity,
unit: 'complexity_score'
@@ -195,14 +205,14 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path entropy
*/
private function extractPathEntropy(string $path): BehaviorFeature
private function extractPathEntropy(string $path): Feature
{
// Character frequency distribution
$chars = str_split(strtolower($path));
$distribution = array_count_values($chars);
return BehaviorFeature::entropy(
type: $this->getBehaviorType(),
return Feature::entropy(
type: $this->getFeatureType(),
name: 'path_entropy',
distribution: array_values($distribution)
);
@@ -211,13 +221,13 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path uniqueness for this client
*/
private function extractPathUniqueness(string $clientId): BehaviorFeature
private function extractPathUniqueness(string $clientId): Feature
{
$pathHistory = $this->pathHistory[$clientId] ?? [];
if (empty($pathHistory)) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_uniqueness',
value: 1.0,
unit: 'ratio'
@@ -229,8 +239,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$uniqueness = $totalPaths > 0 ? $uniquePaths / $totalPaths : 0.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_uniqueness',
value: $uniqueness,
unit: 'ratio'
@@ -240,13 +250,13 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path repetition score
*/
private function extractPathRepetition(string $clientId): BehaviorFeature
private function extractPathRepetition(string $clientId): Feature
{
$pathHistory = $this->pathHistory[$clientId] ?? [];
if (count($pathHistory) < 2) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_repetition',
value: 0.0,
unit: 'score'
@@ -259,8 +269,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$repetition = $totalCount > 0 ? $maxCount / $totalCount : 0.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_repetition',
value: $repetition,
unit: 'ratio'
@@ -270,13 +280,13 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path diversity score
*/
private function extractPathDiversity(string $clientId): BehaviorFeature
private function extractPathDiversity(string $clientId): Feature
{
$pathHistory = $this->pathHistory[$clientId] ?? [];
if (empty($pathHistory)) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_diversity',
value: 0.0,
unit: 'bits'
@@ -285,8 +295,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$pathCounts = array_count_values($pathHistory);
return BehaviorFeature::entropy(
type: $this->getBehaviorType(),
return Feature::entropy(
type: $this->getFeatureType(),
name: 'path_diversity',
distribution: array_values($pathCounts)
);
@@ -295,7 +305,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract suspicious path characteristics score
*/
private function extractSuspiciousPathScore(string $path): BehaviorFeature
private function extractSuspiciousPathScore(string $path): Feature
{
$suspiciousScore = 0.0;
@@ -327,8 +337,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$suspiciousScore += 0.2;
}
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'suspicious_path_score',
value: min($suspiciousScore, 1.0),
unit: 'score'
@@ -338,7 +348,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract file extension pattern
*/
private function extractFileExtensionPattern(string $path): BehaviorFeature
private function extractFileExtensionPattern(string $path): Feature
{
$extension = pathinfo($path, PATHINFO_EXTENSION);
$extension = strtolower($extension);
@@ -355,8 +365,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$riskScore = 0.1; // Any extension is slightly suspicious
}
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'file_extension_risk',
value: $riskScore,
unit: 'risk_score'
@@ -366,7 +376,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract directory traversal score
*/
private function extractDirectoryTraversalScore(string $path): BehaviorFeature
private function extractDirectoryTraversalScore(string $path): Feature
{
$traversalScore = 0.0;
@@ -378,8 +388,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$traversalScore += $matches * 0.3;
}
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'directory_traversal_score',
value: min($traversalScore, 1.0),
unit: 'score'
@@ -389,10 +399,10 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract parameter count
*/
private function extractParameterCount(array $parameters): BehaviorFeature
private function extractParameterCount(array $parameters): Feature
{
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_count',
value: count($parameters),
unit: 'count'
@@ -402,7 +412,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract parameter complexity
*/
private function extractParameterComplexity(array $parameters): BehaviorFeature
private function extractParameterComplexity(array $parameters): Feature
{
$complexity = 0.0;
@@ -418,8 +428,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
}
}
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_complexity',
value: $complexity,
unit: 'complexity_score'
@@ -429,11 +439,11 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract parameter key entropy
*/
private function extractParameterEntropy(array $parameters): BehaviorFeature
private function extractParameterEntropy(array $parameters): Feature
{
if (empty($parameters)) {
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_entropy',
value: 0.0,
unit: 'bits'
@@ -445,8 +455,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$chars = str_split(strtolower($allKeys));
$distribution = array_count_values($chars);
return BehaviorFeature::entropy(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::entropy(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_entropy',
distribution: array_values($distribution)
);
@@ -455,13 +465,13 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract parameter uniqueness for this client
*/
private function extractParameterUniqueness(string $clientId): BehaviorFeature
private function extractParameterUniqueness(string $clientId): Feature
{
$paramHistory = $this->parameterHistory[$clientId] ?? [];
if (empty($paramHistory)) {
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_uniqueness',
value: 1.0,
unit: 'ratio'
@@ -473,8 +483,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$uniqueness = $totalParams > 0 ? $uniqueParams / $totalParams : 0.0;
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_uniqueness',
value: $uniqueness,
unit: 'ratio'
@@ -484,13 +494,13 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract parameter key diversity
*/
private function extractParameterKeyDiversity(string $clientId): BehaviorFeature
private function extractParameterKeyDiversity(string $clientId): Feature
{
$paramHistory = $this->parameterHistory[$clientId] ?? [];
if (empty($paramHistory)) {
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_key_diversity',
value: 0.0,
unit: 'bits'
@@ -507,8 +517,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$keyCounts = array_count_values($allKeys);
return BehaviorFeature::entropy(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::entropy(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_key_diversity',
distribution: array_values($keyCounts)
);
@@ -517,11 +527,11 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract parameter value entropy
*/
private function extractParameterValueEntropy(array $parameters): BehaviorFeature
private function extractParameterValueEntropy(array $parameters): Feature
{
if (empty($parameters)) {
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_value_entropy',
value: 0.0,
unit: 'bits'
@@ -532,8 +542,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$allValues = implode('', array_filter(array_values($parameters), 'is_string'));
if (empty($allValues)) {
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_value_entropy',
value: 0.0,
unit: 'bits'
@@ -543,8 +553,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$chars = str_split(strtolower($allValues));
$distribution = array_count_values($chars);
return BehaviorFeature::entropy(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::entropy(
type: FeatureType::PARAMETER_PATTERNS,
name: 'parameter_value_entropy',
distribution: array_values($distribution)
);
@@ -553,7 +563,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract suspicious parameter score
*/
private function extractSuspiciousParameterScore(array $parameters): BehaviorFeature
private function extractSuspiciousParameterScore(array $parameters): Feature
{
$suspiciousScore = 0.0;
@@ -584,8 +594,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
}
}
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'suspicious_parameter_score',
value: min($suspiciousScore, 1.0),
unit: 'score'
@@ -595,7 +605,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract injection pattern score
*/
private function extractInjectionPatternScore(array $parameters): BehaviorFeature
private function extractInjectionPatternScore(array $parameters): Feature
{
$injectionScore = 0.0;
@@ -621,8 +631,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
}
}
return BehaviorFeature::create(
type: BehaviorType::PARAMETER_PATTERNS,
return Feature::create(
type: FeatureType::PARAMETER_PATTERNS,
name: 'injection_pattern_score',
value: min($injectionScore, 1.0),
unit: 'score'
@@ -632,7 +642,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path sequence entropy
*/
private function extractPathSequenceEntropy(array $pathHistory): BehaviorFeature
private function extractPathSequenceEntropy(array $pathHistory): Feature
{
// Create bigrams (consecutive path pairs)
$bigrams = [];
@@ -643,8 +653,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$bigramCounts = array_count_values($bigrams);
return BehaviorFeature::entropy(
type: $this->getBehaviorType(),
return Feature::entropy(
type: $this->getFeatureType(),
name: 'path_sequence_entropy',
distribution: array_values($bigramCounts)
);
@@ -653,11 +663,11 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract path transition score
*/
private function extractPathTransitionScore(array $pathHistory): BehaviorFeature
private function extractPathTransitionScore(array $pathHistory): Feature
{
if (count($pathHistory) < 2) {
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_transition_score',
value: 0.0,
unit: 'score'
@@ -677,8 +687,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$averageTransition = $transitionScore / (count($pathHistory) - 1);
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'path_transition_score',
value: $averageTransition,
unit: 'similarity_score'
@@ -688,7 +698,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract navigation pattern
*/
private function extractNavigationPattern(array $pathHistory): BehaviorFeature
private function extractNavigationPattern(array $pathHistory): Feature
{
$backtrackingScore = 0.0;
@@ -708,8 +718,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$normalizedScore = count($pathHistory) > 2 ? $backtrackingScore / (count($pathHistory) - 2) : 0.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'navigation_backtracking',
value: $normalizedScore,
unit: 'backtracking_score'
@@ -719,7 +729,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract request complexity
*/
private function extractRequestComplexity(RequestAnalysisData $requestData): BehaviorFeature
private function extractRequestComplexity(RequestAnalysisData $requestData): Feature
{
$complexity = 0.0;
@@ -738,8 +748,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$bodySize = strlen($requestData->body);
$complexity += $bodySize / 5000.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'request_complexity',
value: $complexity,
unit: 'complexity_score'
@@ -749,7 +759,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract header to body ratio
*/
private function extractHeaderToBodyRatio(RequestAnalysisData $requestData): BehaviorFeature
private function extractHeaderToBodyRatio(RequestAnalysisData $requestData): Feature
{
$headerSize = array_sum(array_map(
fn ($name, $value) => strlen($name) + strlen($value),
@@ -761,8 +771,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
$ratio = ($headerSize + $bodySize) > 0 ? $headerSize / ($headerSize + $bodySize) : 0.0;
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'header_body_ratio',
value: $ratio,
unit: 'ratio'
@@ -772,7 +782,7 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
/**
* Extract content type consistency
*/
private function extractContentTypeConsistency(RequestAnalysisData $requestData): BehaviorFeature
private function extractContentTypeConsistency(RequestAnalysisData $requestData): Feature
{
$consistencyScore = 1.0;
@@ -798,8 +808,8 @@ final class PatternFeatureExtractor implements FeatureExtractorInterface
}
}
return BehaviorFeature::create(
type: $this->getBehaviorType(),
return Feature::create(
type: $this->getFeatureType(),
name: 'content_type_consistency',
value: max(0.0, $consistencyScore),
unit: 'consistency_score'