Home / Coverage
Coverage: what has actually been tested
Every cell on this page is generated from the lab test matrix (run 2026-10-23), never typed by hand. A version is only called “blocked” where the test for that exact version and server type passed.
By PHP version and server type
The two flood shapes tested are a file-part flood (max_files) and a field/part flood (max_parts). “Blocked” means the shaped request got HTTP 403 and a log entry at the default limits, on a server with raised caps (the exposed setup). The same runs also sent seven ordinary uploads; none was blocked.
| PHP | CLI server | php-fpm | Apache mod_php | Notes |
|---|---|---|---|---|
| 5.4.16 | blocked | skipped | not tested | php-fpm/cgi-fcgi unavailable; no php:5.4-apache image available |
| 5.5 | not run | The upstream php:5.5 Docker image is broken (corrupt layers on Docker Hub), so no test environment can be built. PHP 5.5 shares the PHP 5 code path with 5.4 and 5.6, which pass. | ||
| 5.6.40 | blocked | blocked | blocked | |
| 7.0.33 | blocked | blocked | blocked | |
| 7.1.33 | blocked | blocked | blocked | |
| 7.2.34 | blocked | blocked | blocked | |
| 7.3.33 | blocked | blocked | blocked | |
| 7.4.33 | blocked | blocked | blocked | |
| 8.0.30 | blocked | blocked | blocked | |
| 8.1.34 | blocked | blocked | blocked | |
| 8.2.35 | blocked | blocked | blocked | |
| 8.3.36 | blocked | blocked | blocked | |
| 8.4.27 | blocked | blocked | blocked | |
| 8.5.12 | blocked | blocked | blocked | |
Totals: 973 passed, 0 failed, 33 skipped. Generated by a script from the raw matrix results. The same data in prose is in docs/coverage.md.
Honest limits of this table
- Apache
mod_phpand php-fpm were both tested on every minor whose cell shows a result — 5.6 and 7.0 through 8.5. PHP 5.4 and 5.5 are the only exceptions (next notes). - PHP 5.4 was tested on PHP's built-in CLI server only: its stock image has no
cgi-fcgi(php-fpm skipped) and there is nophp:5.4-apacheimage. - 1 minors were not independently run: 5.5. They share a generation's code path with a version that passed — a reason to expect they work, not a test result, and not claimed as passing.
- The CVE's
session.upload_progressheader-parsing path was not reproduced. Upload-progress on and off were both tested, to confirm Howdah works either way. - CVE-2012-1823 (php-cgi argument injection) is out of reach and not protected: that query is consumed by php-cgi during its own startup, before any PHP extension loads. It belongs with CVE-2019-11043 — both happen before extension code runs. Use a web-server or front-proxy rule.
- The input-shape and request-header limits are enforced best-effort on the response (the variable is always dropped and logged; the 403 may arrive at request shutdown on lazy-superglobal SAPIs). See Configuration.
- Layer 2 (input inspection, added in 1.1) is not covered by this table. It detects and logs SQL injection, path traversal and command-injection patterns in request values, is best-effort and can be bypassed, which is why it logs, and it does not block by default.
- Layer 3 (sink hardening, added in 1.2) is not covered by this table either; its per-version table is on the home page. It guards command execution,
unserialize,include/requireandeval(the last two on PHP 5.x too since 1.3), plusphar://and SSRF (new in 1.3, both off by default). It detects and logs by default, and does not block unless explicitly armed. It is best-effort and can be bypassed. - phar (1.3): on PHP 5.x/7.x it covers phar metadata deserialization through the stream wrapper; on PHP 8.x it is detection and denial of
phar://use only, with no deserialization claim. The direct Phar API (new Phar,PharData,Phar::loadPhar,Phar::mapPhar,Phar::getMetadata) is not covered. Another extension re-registeringphar, or a static phar build, fails open. - SSRF (1.3): best-effort, resolve-at-check-time detection, not a connection-time boundary. It is bypassed by DNS rebinding, redirects,
curl_multi_*,CURLOPT_RESOLVE/CONNECT_TOand a non-string or absentCURLOPT_URL. Not hooked:copy,file,readfile,SoapClient,DOMDocument::load*,simplexml_load_file. It adds agetaddrinfoper distinct outbound host with no timeout; more than 32 resolved addresses are capped and a host over 256 bytes is treated as suspicious. - PHP 5.x
include(1.3): checked at compile time, so a file served from a warm opcache is not re-inspected.evalis unaffected, and the PHP 7.0+ opcode handler is not affected by opcache. - Provenance: the 1.3 Layer 3 mechanisms were verified on PHP 5.4, 5.6, 7.4, 8.3 and 8.5. Other minors build and are expected to work but are not independently verified. A debug-build leak review is pending.
- Coverage results were recorded on Linux x86_64. aarch64 is build-verified for all 14 minors (PHP 5.4 included since the 1.2.2 build fix); the scenario matrix has not been re-run on arm64.