Skip to content

Latest commit

 

History

History
35 lines (27 loc) · 3.49 KB

COVERAGE.md

File metadata and controls

35 lines (27 loc) · 3.49 KB

Coverage Matrix — What This Project Does and Does Not Stop

A WAF is a virtual patch: it reduces exposure while the real patch rolls out. This page says exactly where each control helps and where it doesn't. A good security engineer knows where a control stops working.

Attack elements vs. controls

Attack element CVE WAF control WAF coverage Server-side control in this repo Residual risk
PHPSESSID + PHP_SESSION_UPLOAD_PROGRESS request pattern 109619 Rule 20 PHP2Shell-Signature + rule 30 PHP2Shell_BODY (PHP rule set Version_2.3) Full, within the inspected part of the body session.upload_progress.enabled=0 (php.ini and php_admin_flag), pm.max_requests=1 Field name past the inspection limit (body > 8 KB on ALB) on the upload path
Stale global state reused by the next request 109619 none (WAF can't see worker memory) None pm.max_requests=1 recycles every worker; patched PHP 8.4.27 None once patched
Multipart uploads both Rule 60 Block-Multipart-FormData outside /upload.php Conditional: full on paths that never take uploads nginx only allows large bodies on /upload.php /upload.php must accept multipart, so it relies on rule 20/30 + patching
Oversized bodies 109618 Rule 70 Block-Oversize-Body (> 8 KB, OversizeHandling: MATCH) Partial post_max_size=32M, nginx client_max_body_size Header amplification: many small part headers fit under 8 KB but expand in memory
PHP running out of memory mid-request 109618 none None memory_limit=-1 + container cgroup limit (--memory 512m), never RLIMIT_AS/RLIMIT_DATA None once patched
Repeated exploitation attempts both Rule 10 RateLimit-Posts (100 POST / 60 s / IP) Partial pm.max_requests=1 One request can be enough; distributed sources evade per-IP limits
fatal_error_backtraces (PHP 8.5 config) 109618 none (server config) None Documented: set 0 on PHP 8.5; not set on 8.4 Operator error on 8.5 hosts
Invalid / deprecated INI diagnostics 109618 none None Hardening file sets only valid directives; log_errors=On to surface warnings Legacy directives in other apps
Per-request config overrides (.htaccess, PHP_VALUE) both none None php_admin_* in the FPM pool; nginx passes no PHP_VALUE —
Exemption bypass via path tricks (/upload.php/../x.php, %2f) — Rules 60/70 match the upload path EXACTLY after URL_DECODE + NORMALIZE_PATH Full nginx serves only exact .php files —

Inspection limits by resource

Resource Default body inspection Max Notes
Application Load Balancer (this lab) 8 KB 8 KB Can't be raised, so rule 70 is required
AWS AppSync 8 KB 8 KB
Amazon CloudFront 16 KB 64 KB association_config → request_body → CLOUDFRONT → KB_64
Amazon API Gateway, Cognito, App Runner, Verified Access 16 KB 64 KB

Moving this design behind CloudFront would raise the limit to 64 KB, so rule 20 could see further into upload bodies.

Bottom line

  • Patch PHP (8.5.12 / 8.4.27 / 8.3.36 / 8.2.35). That's the only complete fix, so variables.tf refuses to deploy an unpatched php_image.
  • Keep session.upload_progress.enabled=0 after patching.
  • Keep or remove the WAF rules after patching depending on whether anything still needs the protection. Rule 60 is a good permanent control on apps that never take uploads.