Source of: /manual/en/security.filesystem.nullbytes.php
<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/security.filesystem.inc";
$setup = array (
'home' =>
array (
0 => 'index.php',
1 => 'PHP Manual',
),
'head' =>
array (
0 => 'UTF-8',
1 => 'en',
),
'this' =>
array (
0 => 'security.filesystem.nullbytes.php',
1 => 'Null bytes related issues',
),
'up' =>
array (
0 => 'security.filesystem.php',
1 => 'Filesystem Security',
),
'prev' =>
array (
0 => 'security.filesystem.php',
1 => 'Filesystem Security',
),
'next' =>
array (
0 => 'security.database.php',
1 => 'Database Security',
),
);
$setup["toc"] = $TOC;
$setup["parents"] = $PARENTS;
manual_setup($setup);
manual_header();
?>
<div id="security.filesystem.nullbytes" class="sect1">
<h2 class="title">Null bytes related issues</h2>
<p class="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:
</p>
<div class="example">
<p><b>Example #1 Script vulnerable to null bytes</b></p>
<div class="example-contents programlisting">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB"><?php<br />$file </span><span style="color: #007700">= </span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'file'</span><span style="color: #007700">]; </span><span style="color: #FF8000">// "../../etc/passwd\0"<br /></span><span style="color: #007700">if (</span><span style="color: #0000BB">file_exists</span><span style="color: #007700">(</span><span style="color: #DD0000">'/home/wwwrun/'</span><span style="color: #007700">.</span><span style="color: #0000BB">$file</span><span style="color: #007700">.</span><span style="color: #DD0000">'.php'</span><span style="color: #007700">)) {<br /> </span><span style="color: #FF8000">// file_exists will return true as the file /home/wwwrun/../../etc/passwd exists<br /> </span><span style="color: #007700">include </span><span style="color: #DD0000">'/home/wwwrun/'</span><span style="color: #007700">.</span><span style="color: #0000BB">$file</span><span style="color: #007700">.</span><span style="color: #DD0000">'.php'</span><span style="color: #007700">;<br /> </span><span style="color: #FF8000">// the file /etc/passwd will be included<br /></span><span style="color: #007700">}<br /></span><span style="color: #0000BB">?></span>
</span>
</code></div>
</div>
</div>
<p class="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:
</p>
<div class="example">
<p><b>Example #2 Correctly validating the input</b></p>
<div class="example-contents programlisting">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB"><?php<br />$file </span><span style="color: #007700">= </span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'file'</span><span style="color: #007700">]; <br /><br /></span><span style="color: #FF8000">// Whitelisting possible values<br /></span><span style="color: #007700">switch (</span><span style="color: #0000BB">$file</span><span style="color: #007700">) {<br /> case </span><span style="color: #DD0000">'main'</span><span style="color: #007700">:<br /> case </span><span style="color: #DD0000">'foo'</span><span style="color: #007700">:<br /> case </span><span style="color: #DD0000">'bar'</span><span style="color: #007700">:<br /> include </span><span style="color: #DD0000">'/home/wwwrun/include/'</span><span style="color: #007700">.</span><span style="color: #0000BB">$file</span><span style="color: #007700">.</span><span style="color: #DD0000">'.php'</span><span style="color: #007700">;<br /> break;<br /> default:<br /> include </span><span style="color: #DD0000">'/home/wwwrun/include/main.php'</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?></span>
</span>
</code></div>
</div>
</div>
</div><?php manual_footer(); ?>