[php-src] Issue #9949: Partial content on POST request with 'chunked' transfer encoding

From: Date: Mon, 14 Nov 2022 14:22:02 +0000
Subject: [php-src] Issue #9949: Partial content on POST request with 'chunked' transfer encoding
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-242820@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/9949 Author: withings-sas ### Description Using sapi_apache2 and performing a POST query with the "transfer-encoding: chunk" header, if the query is interrupted before all chunked/data were sent, PHP still accept the partial content received and execute normally, returning a 200 status. Per RFC, it should return 400, which apache2 does if the php module is not activated. Also php should either not get executed at all, or warned in some way that the content is partial. Looking at this closely, it seems the issue comes from the following code: In function php_apache_sapi_read_post of ``sapi_apache2.c`` lines 196-205 (on PHP8.2 branch): ``` while (ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len) == APR_SUCCESS) { apr_brigade_flatten(brigade, buf, &len); apr_brigade_cleanup(brigade); tlen += len; if (tlen == count_bytes || !len) { break; } buf += len; len = count_bytes - tlen; } return tlen; ``` The return of ``ap_get_brigade`` exit normally if it receives anything other than APR_SUCCESS and in particular does not check if it returns APR_INCOMPLETE in which case it should return a 400 response code. I checked a quick and dirty fix: ``` apr_status_t ast; ast = ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len); while (ast == APR_SUCCESS) { apr_brigade_flatten(brigade, buf, &len); apr_brigade_cleanup(brigade); tlen += len; if (tlen == count_bytes || !len) { break; } buf += len; len = count_bytes - tlen; ast = ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len); } if (ast == APR_INCOMPLETE) { ctx->r->status = 400; } return tlen; ``` And it returns 400 correctly (but clearly I am not suggesting this as the correct fix, just demonstrating that the ap_get_bricade() return code should be taken care of). ### PHP Version 8.0+ ### Operating System Ubuntu 18.04+

« previous php.bugs (#242820) next »