colder Wed Apr 25 14:07:53 2007 UTC
Modified files: /phpdoc/en/security filesystem.xml Log: Mention null bytes related issues http://cvs.php.net/viewvc.cgi/phpdoc/en/security/filesystem.xml?r1=1.4&r2=1.5&diff_format=u Index: phpdoc/en/security/filesystem.xml diff -u phpdoc/en/security/filesystem.xml:1.4 phpdoc/en/security/filesystem.xml:1.5 --- phpdoc/en/security/filesystem.xml:1.4 Tue Apr 17 16:31:00 2007 +++ phpdoc/en/security/filesystem.xml Wed Apr 25 14:07:52 2007 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="iso-8859-1"?> -<!-- $Revision: 1.4 $ --> +<!-- $Revision: 1.5 $ --> <!-- splitted from ./index.xml, last change in rev 1.66 --> <chapter id="security.filesystem"> <title>Filesystem Security</title> @@ -144,6 +144,58 @@ reason, it's usually easier to create a policy where you forbid everything except for what you explicitly allow. </para> + <sect1 id="security.filesystem.nullbytes"> + <title>Null bytes related issues</title> + <simpara> + As PHP uses the underlying C functions for filesystem related + operations, it may handle null bytes in a quite unexpected way. + As null bytes denote the end of a string in C, strings containing them + won't be considered entirely but rather only until a null byte occurs. + + The following example shows a vulnerable code that demonstrates this problem: + </simpara> + <example> + <title>Script vulnerable to null bytes</title> + <programlisting role="php"> +<![CDATA[ +<?php +$file = $_GET['file']; // "../../etc/passwd\0" +if (file_exists('/home/wwwrun/'.$file.'.php')) { + // file_exists will return true as the file /home/wwwrun/../../etc/passwd exists + include '/home/wwwrun/'.$file.'.php'; + // the file /etc/passwd will be included +} +?> +]]> + </programlisting> + </example> + <para> + Therefore, any tainted string that is used in a filesystem operation should always + be validated properly. Here is a better version of the previous example: + </para> + <example> + <title>Correctly validating the input</title> + <programlisting role="php"> +<![CDATA[ +<?php +$file = $_GET['file']; + +// Whitelisting possible values +switch ($file) { + case 'main': + case 'foo': + case 'bar': + include '/home/wwwrun/include/'.$file.'.php'; + break; + default: + include '/home/wwwrun/include/main.php'; +} +?> +]]> + </programlisting> + </example> + </sect1> + </chapter> <!-- Keep this comment at the end of the file