Originally reported by Joseph Richardson @EHLOVader on 2011-11-07 disclosure policy (RFv2.0)
A NULL byte poisoning in URL for both CSS and JS combination script
PHP < 5.3.4
A maliciously formed URL like the following:
/ls_css_combine/?file[]=%2Fconfig%2Fconfig.php%00.css&src_mode=1
Where a NULL byte (%00
) has been encoded between the correct file extension and an expected or "safe" extension. file_info will use the full string, but file_get_contents will only use up to the first null byte due to a NULL byte injection issue related to the C code that PHP relies on for filesystem functions.
This can be used to uncover configuration details, code disclosure, or other sensitive files that could be accessed such as downloadable content, or private files.
Although harder, a blind attack could find multiple things given the feedback for directories that exist or don't exist.
/ls_css_combine/?file[]=%2Fmodules%2Fblog%00.css&src_mode=1
Which will return blank indicating directory exists
/ls_css_combine/?file[]=%2Fmodules%2Fnothing%00.css&src_mode=1
Will return:
/* Asset Error: asset C:/WebDev/SVN/LemonStand/trunk/ls/modules/nothing.css not found. */
Indicating directory and file is nonexistent.
In order to prevent NULL byte poisoning you only need to replace chr(0)
with '' within all input that could have possibly come from the user. As follows:
str_replace(chr(0), '', $string);
I suggest the folowing diff to correct the issues:
--- \phproad\system\combine_resources.php Mon Nov 07 15:18:00 2011
+++ \phproad\system\combine_resources.php Mon Nov 07 17:10:53 2011
@@ -60,14 +60,14 @@
foreach($files as $url)
{
- $file = urldecode($url);
+ $file = str_replace(chr(0), '', urldecode($url));
if (array_key_exists($file, $aliases))
$file = $aliases[$file];