Sanitized PHP Include Navigation through GET variable
We all have heard about the Remote File Inclusions, LFI, sql injections and all the other nasty variations of php “hacking”.
This mainly happens because people code pages without being aware of the security of their product.
In this tutorial I will explain how to sanitize a GET variable.
This programming design is used to build pages without using iframes or frames and to optimize the homepage for search engines.
An url usually looks like www.domain.com/index.php?p=about .
include $_GET['page'];
Let’s take this piece of code for example, a normal url would look like www.domain.com/index.php?page=about.php. Now, an attacker could exploit this by simply changing the about.php into some shellcode like c99 or r57.
He would include an evil piece of code that is often used to deface homepages.
The solution to this problem would be to check if the file exists, and if it doesn’t, then it should include an error page.
We can use a function in PHP called file_exists.
file_exists($file);
It basically checks if the file exists in the current folder or not.
$file = $_GET['page'].'.php';
if (file_exists($file)) {
include $file;
}else{
echo 'Error';
}
This would already do the job.
You could also filter the forward slashes (/) and the double-dots(..) and delete them from $file.
The only problem is that the evil user can access all your files trough the ?page=”page here”.
We can define which pages we want to allow with an array. This is a quite simple task to do with PHP, god bless those useful functions, I mainly code in Pascal (at school) and pascal has very few really useful functions…
We define an array with all the pages we want to allow and then use the function in_array.
We could also check if there are symbols such as / and .. inside the requested page and delete them.
This is the syntax for the str_replace function.
str_replace ("Text to find","Replace by",$_GET["page"]);
The check would look like this
$allowed = array('page1','page2','page3');
$selection = str_replace ('..','',$_GET['page']);
$selection = str_replace ('/','',$_GET['page']);
if(in_array($selection,$allowed) && file_exists($selection)){
include $selection;
}
}else{
echo 'error, unauthorized page';
}
August 31, 2008 at 5:58 pm
Jolly good show of spelling out an important concept.
September 20, 2008 at 1:17 pm
Great article. I had this problem with some sites I built before – and I didn’t take the time to sanitize (I KNOW I KNOW!). I’ve had to learn the hard way. Instead of including files, one of my clients has a backend system where they can modify each page – so the request pulls up a database entry rather than a page – but this worked out for that just the same. I just pulled every page in the DB and only authorize those. I also put in a little “unauthorized_requests” log for logging whenever someone is tampering or just stumbles on the wrong page.
Great site!
December 4, 2008 at 11:35 pm
^_^ Don’t worry, I think most of us learnt it the hard way. Error is human.. Anyone got more bad experiences?
February 20, 2009 at 1:20 am
no need for you to do the str replace in this example, and it isnt worth checking file_exist either (because if you added it to safe array it must exist right?
)
however you should be checking that the get variable exists before you index it!
so I would say the code is:
if ( ! isset($_GET['page']) and ! in_array($_GET['page'], $allowed))
{
die;
}
include $_GET['page'];
February 20, 2009 at 5:11 pm
Parkinm, thanks
I have evolved my skills quite a bit. This example makes me laugh
Thanks
April 3, 2009 at 6:29 am
care to post an updated example?
April 3, 2009 at 7:10 am
Hi, sure I will post an updated example soon.
It might take a while because I’m currently doing an internship.
Thanks for the interest.