Wednesday, August 10. 2005
Some weeks ago I have publicly disclosed 2 serious flaws in the PHP Security Guide of the PHP Security Consortium. The PHP community surely remembers the harsh response from the PHPSC leader in response to my publication. Until today he still claims, that the flaws only exist in my imagination (which is very strange because he has fixed them without proper credits) and that I haven't contacted 5 people among the consortium prior to my public disclosure.
Having learned from that experience I sent another flaw in their documentation directly to their official contact address, which is mentioned on their website. This time the flaw is located in their article about howto use Text_CAPTCHA.
This was 2 weeks ago and until today I haven't heard a single line of response. In the meanwhile I have emailed with another security professional from openwall.com and learned that his email with comments about their password hashing article was also ignored.
If you have already read my previous publication, you will realise, that the new flaw is very similiar to the one I previously disclosed in their chapter about CSRF. This suggests that I need to explain the behaviour of the $_SESSION superglobal more clearly, because it is obviously misunderstood by the author of the following example (which was copied directly from his article).
<?php
session_start();
if (isset($_POST['captcha_phrase']) &&
$_POST['captcha_phrase'] == $_SESSION['captcha_phrase'])
{
/* Human */
}
else
{
/* Computer */
}
?>
In this example session_start() is called. This will result in a new session being created if there is no or an unknown session identifier provided. This means the content of the global variable $_SESSION will be deleted and replaced with a new empty $_SESSION superglobal (only on the first call to session_start()). This means that $_SESSION['captcha_phrase'] is uninitialised when it is compared to the POST variable captcha_phrase. This also means that the check in place will evaluate as true if the supplied captcha_phrase is just an empty string.
This actually means a robot can simply provide an unknown session identifier (or none at all) and supply an empty string as answer to the CAPTCHA and will be identified as human. This is a 100% failure of the intended purpose of a CAPTCHA.
Now one could argue that this is only a snippet and not a full example, but this is only a lame excuse, because a) there is a session_start() which would not be needed in a snippet and b) similiar code like this was already found in the wild. How should a PHP newbie know, that the examples from the PHP Security Consortium cannot be trusted and need to be fixed before they can be used.