Bug #21229 [Com]: fgets never times out with malicious server

From: Date: Tue, 11 Jul 2017 10:24:20 +0000
Subject: Bug #21229 [Com]: fgets never times out with malicious server
References: 1  Groups: php.pear.bugs 
Request: Send a blank email to pear-bugs+get-11394@lists.php.net to get a copy of this message
Edit report at https://pear.php.net/bugs/bug.php?id=21229&edit=1 ID: 21229 Comment by: mmn at hethane dot se Reported By: mmn at hethane dot se Summary: fgets never times out with malicious server Status: Open Type: Bug Package: HTTP_Request2 Operating System: Debian Package Version: 2.3.0 PHP Version: Irrelevant Roadmap Versions: New Comment: Maybe the "reset timeout" code below this patch is no longer necessary, but I don't want to put too much into the patch either. Previous Comments: ------------------------------------------------------------------------ [2017-07-11 06:23:07] mmn I think the stream_select solution I have added as a patch here should work well as a solution too. It'll force fgets to stick within the given time parameter (unless both localTimeout and deadline is null, then null is given which is infinite time). I think I've formatted the patch properly for v2.3.0, let me know otherwise. I've patched this in the bundled library for GNU social, where I experienced this issue, here: https://git.gnu.io/gnu/gnu-social/commit/05a9c11c476b384e5ef3f3cc83b66406fcf7a378 ------------------------------------------------------------------------ [2017-07-11 06:19:50] mmn Added #patch bug:21229;patch:stream_select_for_fgets;revision:1499768390;. ------------------------------------------------------------------------ [2017-07-10 16:13:34] mmn Description: ------------ The usage of 'fgets' in HTTP_Request2_SocketWrapper -> readLine makes it possible for remote servers to reply r-e-a-l-l-y s-l-o-w-l-y and thus blocking a PHP process. It seems that 'fread' will time out properly, while 'fgets' does not: https://secure.php.net/fgets vs. https://secure.php.net/fread In practice, fread seems to appropriately time out when reading from an extremely slow stream, while fgets simply continues until it reaches bufferSize (default 16Ki) or a newline (a malicious server can choose to never send a newline, causing a script to time out only after 16000 seconds because of the buffer size having to be filled up). It seems to fix this, we should have a small internal buffer and make sure to use 'fread' instead of 'fgets' but simulate the stop-at-newline functionality as it's often used to read in HTTP headers etc. A thread related to this in GNU social's use of HTTP_Request2 can be found here: https://git.gnu.io/gnu/gnu-social/issues/281#note_5674 ------------------------------------------------------------------------ -- Edit this bug report at https://pear.php.net/bugs/bug.php?id=21229&edit=1

« previous php.pear.bugs (#11394) next »