Skip to content

v2.5.0

Choose a tag to compare

@sean-e-dietrich sean-e-dietrich released this 19 Dec 16:52

Changelog v2.5.0

🎉 Major Features

Production-Ready Presets

Three new comprehensive security presets have been added to the presets/ directory for immediate deployment:

1. Malicious Request Detection (presets/malicious-requests.yml)

Advanced vulnerability scoring system that detects and blocks malicious requests based on multiple risk factors:

  • 50+ Attack Pattern Signatures: SQL injection, XSS, command injection, path traversal, RCE, web shells, XXE, SSRF, template injection
  • 20+ User Agent Rules: Detects automated attack tools (SQLMap, Nikto, Nmap, Metasploit, etc.)
  • Multi-Factor Risk Scoring: Combines HTTP method, attack patterns, user agents, and optional GeoIP data
  • Progressive Penalties: Escalating ban durations (1 hour → 7 days) based on threat severity
  • 5 Risk Levels: Low, medium, high, critical, and extreme with configurable thresholds
  • Optional GeoIP Integration: Country and ASN-based scoring when GeoIP databases are configured

2. Rate Limiting (presets/rate-limiting.yml)

Production-ready rate limiting configuration protecting against abuse and resource exhaustion:

  • 48 Pre-configured Rules: Covering authentication, APIs, WordPress, forms, static assets, webhooks, and more
  • 4 Storage Backends: Redis (recommended), Database, File, or PSR-6 Cache
  • Graduated Limits: Different rate limits for different endpoint types
    • Login: 5 attempts per 5 minutes
    • API: 100 requests per minute
    • Static Assets: 500 requests per minute
    • Health Checks: 1000 requests per minute
  • Smart Defaults: 60 requests per minute for general traffic
  • HTTP 429 Status: Proper "Too Many Requests" response

3. Malicious URL Blocking (presets/malicious-urls.yml)

Blocks common malicious PHP files, attack patterns, and suspicious URLs:

  • 30+ Regex Patterns: Known backdoor files, web shells, and attack files
  • Query/POST Protection: Blocks code execution attempts via parameters
  • Generic PHP Blocking: Optional catch-all to block all PHP files except index.php
  • WordPress Protection: Specific protections for WordPress installations

New Documentation

Example Directory (example/README.md)

Comprehensive 400+ line guide covering:

  • Docker environment setup and usage
  • Testing with X-Forwarded-For headers for remote IP simulation
  • Complete GeoIP database setup instructions (MaxMind GeoLite2)
  • Configuration examples for all major plugins
  • Troubleshooting guide

Presets Documentation (presets/README.md)

Extensive 650+ line documentation including:

  • Detailed description of all presets
  • Quick start guides for each preset
  • GeoIP enablement instructions
  • Rate limiting storage configuration for all backends
  • Customization examples
  • Testing commands and scenarios
  • Common false positives and solutions
  • Layered security approach combining multiple presets

Rate Limiting Reference (presets/RATE-LIMITING-REFERENCE.md)

Quick reference guide with:

  • Complete table of all 48 rate limits
  • Storage backend comparison matrix
  • Common customization examples
  • Troubleshooting guide
  • Best practices
  • Performance benchmarks

Example Configurations

  • presets/example-malicious-requests-usage.yml: 10 usage scenarios
  • presets/example-rate-limiting-usage.yml: API-only, e-commerce, WordPress-specific configs
  • presets/example-usage.yml: General preset usage examples

🔧 Configuration System Enhancements

Plugin Configuration Merging

Enhanced ConfigLoader::mergeConfigs() with intelligent plugin-specific merging:

Preserve Priority: When merging plugin configs, the priority from the first config is preserved

# base.yml
block:
  Plugin:
    priority: -100
    config: [rule1]

# override.yml
block:
  Plugin:
    priority: 50  # This will be IGNORED
    config: [rule2]

# Result: priority=-100, config=[rule1, rule2]

Append Config Arrays: Plugin config arrays are merged (appended) instead of replaced

# Before: Second config replaced first config
# After: Configs are combined [rule1, rule2, rule3]

Enable Flag Handling: Smart 4-way logic for enable: false

  • Both enabled → Merge configurations
  • Base disabled, override enabled → Replace entirely with override
  • Override disabled → Ignore override completely
  • Both disabled → Remove plugin from final config

Path Tracking: Internal path tracking for intelligent merging decisions

Environment Variable Enhancements

Added _SERVER superglobal support to token substitution:

storage:
  file: '%env(_SERVER.DOCUMENT_ROOT)%/firewall.data'

🛡️ Security & Validation

Regex Pattern Validation

Complete rewrite of regex pattern handling to eliminate warnings and improve security:

New Validation Method (EvaluateTrait::isValidRegexMatch())

  • Validates delimiter format (must be non-alphanumeric)
  • Checks delimiter matching (opening/closing delimiters must match)
  • Validates minimum pattern length (at least 3 characters)
  • Detects all PCRE errors (backtrack limit, recursion limit, UTF-8 errors, etc.)
  • Returns false gracefully instead of throwing warnings
  • Logs detailed error messages for debugging

Error Handling: Comprehensive error detection and logging

  • Internal PCRE errors
  • Backtrack limit exhausted
  • Recursion limit exhausted
  • Malformed UTF-8 data
  • Bad UTF-8 offset
  • JIT stack limit exhausted

All Presets Updated: All 30+ regex patterns in presets now use proper delimiters

# Before (invalid):
- path@regex:^/test\.php$

# After (valid):
- path@regex:#^/test\.php$#

Regex Pattern Documentation

Added comprehensive regex delimiter documentation in both example/README.md and presets/README.md:

  • Valid vs invalid pattern examples
  • Delimiter selection guidance
  • Error handling instructions
  • Support for multiple delimiters (#, /, @, ~)

🐛 Bug Fixes

PHPStan Boolean Logic Issue (ConfigLoader.php:288)

Issue: Redundant condition !$baseEnabled && $overEnabled where right side was always true

Fix: Simplified to !$baseEnabled since the case where both are false is already handled earlier

Impact: Cleaner code, passes PHPStan static analysis

Regex Comma Splitting Issue

Issue: Regex patterns with commas in quantifiers (e.g., {1,2}) were incorrectly split into arrays

Fix: Removed 'regex' from multi-value operators list in EvaluateTrait::parseSimpleStringRule()

Impact: Patterns like path@regex:#/[a-z]{1,2}\.php$# now work correctly

Matches Mode Extraction

Issue: Simple explode('#') on patterns was breaking regex patterns using # as delimiter

Fix: Changed to regex pattern match /#(any|all|none|some)$/i to only match valid modes at end of string

Impact: Patterns like #^/test# with # delimiter now work correctly

📝 Testing

New Test Coverage

  • 3 new URL plugin tests: Invalid regex handling, different delimiters, modifiers
  • 5 new ConfigLoader tests: Plugin config merging scenarios
  • Total Tests: 526 unit tests (all passing)
  • Total Assertions: 969 assertions

Test Categories

  • Invalid regex patterns handled gracefully
  • Regex with different delimiters (/, #, @, ~)
  • Regex with modifiers (case-insensitive, multiline)
  • Plugin config merging (priority preservation, config appending, enable flag logic)

📦 New Files

Presets

  • presets/malicious-requests.yml (495 lines)
  • presets/rate-limiting.yml (371 lines)
  • presets/malicious-urls.yml (170 lines)
  • presets/wordpress.yml (124 lines)
  • presets/storage-pantheon.yml (10 lines)
  • presets/logging-pantheon.yml (5 lines)

Documentation

  • presets/README.md (665 lines)
  • presets/RATE-LIMITING-REFERENCE.md (280 lines)
  • example/README.md (406 lines)

Examples

  • presets/example-malicious-requests-usage.yml (149 lines)
  • presets/example-rate-limiting-usage.yml (287 lines)
  • presets/example-usage.yml (141 lines)
  • presets/config.yml (3 lines)

🔄 Modified Files

Core Changes

  • src/Traits/EvaluateTrait.php: Added regex validation, fixed comma splitting
  • src/Utility/ConfigLoader.php: Enhanced plugin merging, added _SERVER support
  • tests/Unit/Plugins/UrlTest.php: Added regex validation tests
  • tests/Unit/Utility/ConfigLoaderTest.php: Added plugin merging tests

Configuration

  • example/config.yml: Updated with comprehensive examples
  • example/index.php: Enhanced with better error handling and metrics

📊 Statistics

  • 3,756 lines added across 22 files
  • 76 lines removed
  • 526 unit tests (all passing)
  • 969 assertions
  • 0 PHPStan errors
  • 3 new production-ready presets
  • 1,350+ lines of new documentation

🚀 Upgrade Guide

From v2.4.0

No Breaking Changes: This release is fully backward compatible with v2.4.0.

New Features to Try:

  1. Use presets for instant protection:

    configs:
      - presets/malicious-requests.yml
      - presets/rate-limiting.yml
  2. Enable GeoIP scoring (optional):
    Download GeoIP databases and uncomment the country/ASN sections in malicious-requests.yml

  3. Configure rate limiting storage:
    Update the storage section in rate-limiting.yml to use Redis or your preferred backend

  4. Fix regex patterns: If you have custom regex patterns without delimiters, add them:

    # Update from:
    - path@regex:^/test$
    # To:
    - path@regex:#^/test$#

📚 Resources


Full Changelog: v2.4.0...v2.5.0