<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Null bytes related issues</title> </head> <body><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="security.filesystem.html">Filesystem Security</a></div> <div class="next" style="text-align: right; float: right;"><a href="security.database.html">Database Security</a></div> <div class="up"><a href="security.filesystem.html">Filesystem Security</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div><hr /><div id="security.filesystem.nullbytes" class="sect1"> <h2 class="title">Null bytes related issues</h2> <p class="simpara"> As <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> 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" id="example-331"> <p><strong>Example #1 Script vulnerable to null bytes</strong></p> <div class="example-contents"> <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" id="example-332"> <p><strong>Example #2 Correctly validating the input</strong></p> <div class="example-contents"> <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><hr /><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="security.filesystem.html">Filesystem Security</a></div> <div class="next" style="text-align: right; float: right;"><a href="security.database.html">Database Security</a></div> <div class="up"><a href="security.filesystem.html">Filesystem Security</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div></body></html>