Skip to main content

Did I find a bug in PHP"s `crypt()`?



I think I may have found a bug in PHP's crypt() function under Windows.





However : I recognize that it's probably my fault . PHP is used by millions and worked on by thousands; my code is used by tens and worked on by me. (This argument is best explained on Coding Horror .)





So I'm asking for help: show me my fault. I've been trying to find it for a few days now, with no luck.





The setup





I'm using a Windows server installation with Apache 2.2.14 (Win32) and PHP 5.3.2. My development box runs Windows XP Professional; the 'production' server (this is an intranet setup) runs Windows Storage Server 2003. The problem happens on both.





I don't see anything in php.ini related to crypt() , but will happily answer questions about my config.





The problem





Several scripts in my PHP app occasionally hang: the page sits there on 'waiting for localhost' and never finishes. Each of these scripts uses crypt to hash a user's password before storing it in the database, or, in the case of the login page, to hash the entered password before comparing it to the version stored in the database.





Since the login page is the simplest, I focused on it for testing. I repeatedly logged in, and found that it would hang maybe 4 out of 10 times.





As an experiment, I changed the login page to use the plain text password and changed my password in the database to its plain text version. The page stopped hanging.





I saw that PHP's latest version lists this bugfix:







Fixed bug #51059 (crypt crashes when invalid salt are [sic] given).







So I created a very simple test script, as follows, using the same salt given in an official example :







$foo = crypt('rasmuslerdorf','r1');

echo $foo;







This page, too, will hang, if I reload it like crazy. I only see it hanging in Chrome, but regardless of browser, the effect on Apache is the same.





Effect on Apache





When these pages hang, Apache's server-status page (which I explained here , regarding a different problem) increments the number of requests being processed and decrements the number of idle workers. The requests being processed almost all have a status of 'Sending Reply,' though sometimes for a moment they will show either 'Reading request' or 'keepalive (read).'





Eventually, Apache may crash . When it does, the Windows crash report looks like this:







szAppName: httpd.exe

szAppVer: 2.2.14.0

szModName: php5ts.dll

szModVer: 5.3.1.0 // OK, this report was before I upgraded to PHP 5.3.2,

// but that didn't fix it

offset: 00a2615







Is it my fault?





I'm tempted to file a bug report to PHP on this. The argument against it is, as stated above, that bugs are nearly always my fault.





However, my argument in favor of 'it's PHP's fault' is:





  1. I'm using Windows, whereas most servers use Linux (I don't get to choose this), so the chances are greater that I've found an edge case



  2. There was recently a bug with crypt() , so maybe it still has issues



  3. I have made the simplest test case I can, and I still have the problem







Can anyone duplicate this? Can you suggest where I've gone wrong? Should I file the bug after all?





Thanks in advance for any help you may give.



Source: Tips4all

Comments

  1. The bugs 51059 (only about passing invalid inputs) or 50947 (not the same code, 5.3 has new algorithms and features implemented in php, on all platforms) are not related to this problem.

    However http://bugs.php.net/bug.php?id=51424 is. I already posted a partial patch there, but it solves most of the possible locks but it is indeed not sufficient. A full fix will be present in the next 5.3 release.

    By the way, it is not windows specific but about the threaded SAPI (windows apache 2.2 for example).

    ReplyDelete
  2. Yes. It's a known bug,

    http://bugs.php.net/bug.php?id=50947

    You can simulate the crypt() result using mcrypt. If you can change your password hash, you should really use hash_hmac(), which is more secure and we have no issues with it On Apache. No experiences on Windows though.

    ReplyDelete
  3. This question has now been viewed 128 times and upvoted 9 times. The only answer I've received says it's a bug, and points to one in the PHP bug database. I don't think it's exactly the same one, but it does seem to validate my diagnosis.

    Therefore, with some hesitation, I have filed a bug report:

    Bug #51666 - Using crypt() makes Apache hang or crash

    Thanks to everyone who has looked at this with me - even if you didn't reply, just knowing that others were considering this with me, and not telling me I'm crazy, has been helpful.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.