Is it secure to use the following code:
require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $_GET['page'] . ".php")
Is it secure to use the following code:
require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $_GET['page'] . ".php")
No, it is not secure. Why?
Because sequence of two dots /../ means one directory back and the attacker could potentially include anything on your system, even above $_SERVER['DOCUMENT_ROOT']
. (In an unfortunate configuration that means secret/sensitive OS config files.)
You have to IF or SWITCH for the allowed values to prevent malicious input. Example:
switch($_GET['page']) {
case 'welcome': $page='welcome';
case 'shop': $page='shop';
default: $page='index';
}
require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $page . ".php")
Also check out in_array()
for a little easier filtration.
StackOverflow has a useful Q&A for how to sanitize user input with PHP. It's a few years old, but the principles haven't changed at all.
The quick answer is: if you can avoid the problem in the first place, you're better off.
Show us how you're trying to use this, and we may be able to offer suggestions for improvement.
It's not secure. You can use array with allowed values. For example
$allowed_pages = array('index', 'test', 'my_page')
if (!in_array($_GET['page'], $allowed_pages)){
echo 'good bye';
die();
} else {
//
}
If you trust all the files in the pages dir try:
if (in_array($_GET['page'],glob("/pages/*.php"))) {
require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $_GET['page'] . ".php");
} else echo "Nice try hacker!";
Here's another solution using parts of a function I use to clean uploaded filenames:
OPTION #2 thanks Daniel, Rok!
$page = preg_replace('/[^a-zA-Z0-9_ %\[\]\.\(\)%&-]/s', '', $_GET['page']);
$filename = $_SERVER['DOCUMENT_ROOT'] . "/pages/" . str_replace("/",'',$page) . ".php";
if (file_exists($filename)) {
require($filename);
} else echo "Nice try hacker!";
Note that this will only work if there are no special characters in your file names