Including Files Based on Input
Validating Include Paths
The solution is, instead of just blindly including the file, we check for any directory navigation symbols in the submitted value before the file is included. I will show you how to create a function we can run the value through before executing the include.
The following script demonstrates how it works. You will need a text file to experiment with:
kumquat.txt
<h3>Kumquat</h3>
<p>Any of several trees or shrubs of the genus Fortunella bearing small orange-colored edible fruits
with thick sweet-flavored skin and sour pulp.
</p>
And this PHP page: safeinc.php:
<?php
print "<h2>Testing Safe Include</h2>";
function is_safe_file_path($path) {
if ((!eregi("^..",$path)) && (!eregi("^.",$path))){
return true;
}
else {
return false;
}
}
$include_path = "kumquat.txt";
?>
Including: <?php print $include_path; ?>
<div class="note" style="background: #eeeeee; color: #333333; border: 1px dashed;
padding: 4px; font: 12px Arial">
<?php
if(is_safe_file_path($include_path)){
include($include_path);
}
?>
</div>
Put both files in the same directory and run safeinc.php to see the result. You can try entering "../" or "./" or "../../" or "../kumquat.txt" etc. into the $include_path to see it reject those paths with unsafe path symbols.
Be sure to form your full path, such as "fruits/kumquat.txt" before running it through the function and including.
Of course, you can have paths that go deeper in the directory tree like the previous, but not "../fruits/kumquat.txt" because that is what we are trying to prevent: navigating out of the folder we are in.
For this example, I also left out encapsulating the include into a function to make it easier to understand (and code!). Here's a version of safeinc.php that wraps the include into a function.
safeincfn.php:
<?php
print "<h2>Testing Safe Include</h2>";
function is_safe_file_path($path) {
if ((!eregi("^..",$path)) && (!eregi("^.",$path))){
return true;
}
else {
return false;
}
}
function safe_include($path) {
if(is_safe_file_path($path)){
include($path);
return true; // indicate success
}
}
$include_path = "kumquat.txt";
?>
Including: <?php print $include_path; ?>
<div class="note" style="background: #eeeeee; color: #333333; border: 1px dashed; padding: 4px; font: 12px Arial">
<?php
safe_include($include_path);
?>
</div>
Or a more compact function that folds all the features into one:
<?php
function safe_include($path) {
if ((!eregi("^..",$path)) && (!eregi("^.",$path))){
include($path);
return true; // indicate success
}
else {
return false;
}
}
?>
Or with built-in warning and script halt. Silent on success, display message on fail.
<?php
function safe_include($path) {
if ((!eregi("^..",$path)) && (!eregi("^.",$path))){
include($path);
}
else {
print "Warning - you do not have permission to access this area.";
exit;
}
}
?>
Pages: 1 2 | Related Forum Topics | More Tutorials » |