Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:89511 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 32225 invoked from network); 1 Dec 2015 12:48:59 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Dec 2015 12:48:59 -0000 Authentication-Results: pb1.pair.com header.from=nikita.ppv@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=nikita.ppv@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.160.196 as permitted sender) X-PHP-List-Original-Sender: nikita.ppv@gmail.com X-Host-Fingerprint: 209.85.160.196 mail-yk0-f196.google.com Received: from [209.85.160.196] ([209.85.160.196:34533] helo=mail-yk0-f196.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D5/47-13465-A379D565 for ; Tue, 01 Dec 2015 07:48:58 -0500 Received: by ykay124 with SMTP id y124so513724yka.1 for ; Tue, 01 Dec 2015 04:48:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=U1I16D1IKTCXSrm5AAyeidkjhlxSlowJ3IHxIYhaY98=; b=Uq2fbizvWSIMDsm+17BBvuZ0jTg6chUa/48QGjkKifXZcBMiQPxYOQC0D4n4Vyj99+ vM0j0KrANBqrOazLf9jAzPOTIdrH/KyG1S+kzSKA/4CvPtrqw7dCuNCwfeCRn31XRMu7 84nMvS5D0EWHm9FF9aZLyEZilg2VEXBGn5HIzieUUjvZyXMtMAM1iH74u8D2Iph7S/sq 7ZTBHzw8SC7wRWmdcxJG0JBJ2BSzFPX+N4f4AAZLD6V00CzI5VlsLz4gzHWw9FIzSIot 5fHCAxDZpAzSgmrkWDpx3dpHauXBu0h7TW69Z1z8ohCdewJTp5zgBVnAn+XU7HxA9aGT zJwQ== MIME-Version: 1.0 X-Received: by 10.129.50.214 with SMTP id y205mr26258274ywy.147.1448974135761; Tue, 01 Dec 2015 04:48:55 -0800 (PST) Received: by 10.13.248.130 with HTTP; Tue, 1 Dec 2015 04:48:55 -0800 (PST) In-Reply-To: References: Date: Tue, 1 Dec 2015 13:48:55 +0100 Message-ID: To: Dmitry Stogov Cc: PHP internals , Anatol Belski , Remi Collet Content-Type: multipart/alternative; boundary=001a114090e4a6a3af0525d59469 Subject: Re: [PHP-DEV] HashDos protection From: nikita.ppv@gmail.com (Nikita Popov) --001a114090e4a6a3af0525d59469 Content-Type: text/plain; charset=UTF-8 On Tue, Dec 1, 2015 at 10:50 AM, Dmitry Stogov wrote: > Hi Nikita, > > few notes: > > It looks like the patch messes the attempt of catching the problem (few > lines related to zend_hash_find_bucket changes) with optimization to > compensate collision check overhead (everything else). I think it's better > to separate these parts. > The addition of zend_hash_add_or_return() isn't an optimization, it is required to ensure that the check happens in all relevant cases. The code previously used a combination of zend_hash_find() and zend_hash_add_new(). However the whole purpose of the zend_hash_add_new() function is to skip the part of the insertion operation where the collision count would be done. At this point I could either a) also count collisions in zend_hash_find(), which is imho not a good option as it's enough to count once and not at every lookup, or b) avoid the combination of zend_hash_find() and zend_hash_add_new() by introducing a new zend_hash_add_or_return() function (which does the same as the previous combination but also performs the collision count). Alternatively I would also simply make zend_hash_add_new() the same as zend_hash_add(), which is probably not wanted either. > Introduction of zend_hash_add_or_return() in 7.0.1 is going to make > forward incompatibility with 7.0.0. However, we may reserve it for internal > usage removing ZEND_API. > I'm fine with not marking it ZEND_API in 7.0. > I don't think PHP should prevent user from construction of arrays he > likes, because of internal problems (like in your example). > > > $s = 1 << 16; $a = []; > > for ($i = 0; count($a) < $s; $i += $s) { $a[$i] = 0; } > > It makes performance problem, but it doesn't mean we should kill it. > We have "max_execution_time" to catch them all. > > I think only big arrays coming from external sources should be checked. > There is no way for PHP to know whether or not an array is constructed from an external source. Yes, of course we can special case json_decode() and unserialize(), but this would not fix the vulnerability for any array that is created in PHP code. It's not exactly unusual to create arrays which are in some way based on user input. Your solution is incomplete, anyway, because of crafting a single list with > 10000 collisions, attacker will able to use N lists with 1000 collisions. > One list with N*1000 collisions and N lists with 1000 collisions each have very different asymptotic complexity. The former is O(N^2), while the latter is O(N). The DOS attack is based on having O(N^2) complexity. Nikita --001a114090e4a6a3af0525d59469--