Sun, 04 Mar 2007


Since Stefan Esser left the PHP Security Response Team there have been countless of pseudo security fixes to the PHP CVS. With pseudo security fixes we mean replacing safe calls of functions considered unsafe (like strncpy, sprintf) with calls to functions considered more secure (e.g. strlcpy, spprintf).

Unfortunately these changes were done very sloppy and had to be reverted in several places, because they actually broke the underlying code and some user complained about it. There is however a place within the WDDX extension where a buffer overflow was introduced to the code that can be triggered by specially crafted (malformed) WDDX packets. Because of this it is very unlikely that a user will complain about it and therefore without this advisory it would most probably make it into the next PHP release.

Affected versions

Affected is only the CVS version of PHP.

Detailed information

During the last week the following strncpy -> strlcpy change was added to the CVS that is completely broken.

--- wddx.c	2007/02/24 02:17:27
+++ wddx.c	2007/02/24 17:59:45
@@ -16,7 +16,7 @@
-/* $Id: wddx.c,v 2007/02/24 02:17:27 helly Exp $ */
+/* $Id: wddx.c,v 2007/02/24 17:59:45 iliaa Exp $ */
 #include "config.h"
@@ -1034,10 +1034,9 @@
    Z_STRVAL_P(ent->data) = estrndup(decoded, decoded_len);
    Z_STRLEN_P(ent->data) = decoded_len;
 } else {
-   Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data),
-   Z_STRLEN_P(ent->data) + decoded_len + 1);
-   strncpy(Z_STRVAL_P(ent->data)+Z_STRLEN_P(ent->data), decoded, decoded_len);
    Z_STRLEN_P(ent->data) += decoded_len;
+   Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data), Z_STRLEN_P(ent->data) + 1);
+   strlcpy(Z_STRVAL_P(ent->data) + Z_STRLEN_P(ent->data), decoded, Z_STRLEN_P(ent->data) + 1);
    Z_STRVAL_P(ent->data)[Z_STRLEN_P(ent->data)] = '\0';

For any C programmer it should be obvious that the bold marked places are wrong. The correct function to call would be strlcat(), not strlcpy() and the additive term is wrong, too.

Because of this little glitch the WDDX deserialisation code does now contain a buffer overflow that is triggered by for example a <string> tag that is interrupted by another tag. A situation that will only occur in malformed (attacker supplied) WDDX packets.

Proof of concept, exploit or instructions to reproduce

Because this vulnerability exists only within the CVS version of PHP and we just did find it we did not create a code execution exploit yet. We however do not doubt that such an exploit is possible and will most probably provide proof until the end of this month. Until then you can play with the attached POC that just crashs PHP in the memory manager.


We can understand that the PHP developers perfom all these changes to the PHP source in order to make it more secure. But we urge them to check their changes multiple times before commiting. Changed like the WDDX case are very dangerous, because they are only triggered by malformed packets and therefore they won't be found unless a security audit reveals them.

And with changes like these they only prove our points.