Local File Inclusion is quite simply the act of including files that are stored on the web server you are interacting with. LFI’s twin, Remote File Inclusion, is based on the same concept, although, as the name implies, you include files that are not stored locally on the server.
The big danger regarding LFI vulnerabilities, is the fact that an attacker may gain unauthorized access and be given permission to read files he/she normally wouldn’t be able to, e. g. configuration files, passwords, credentials, and source code, to name a few. A clever attacker may also be able to use some operating-system specific tricks to gain full access over the machine. That however, is out of the scope of this article.
Let’s say we have a server with an index.php file that looks like this:
As you might guess, this sourcecode of the page looks something like this:
<?php $language = $_GET['language']; include($language); ?>
The server uses the language variable passed in the address bar to choose which language the user shall be welcomed with. This can be done very easily by creating files with names like eng, nor and so on. The problem with this page is that the language variable is not validated. This means that the server does not check it before it starts using it. This is a mistake that is easy to make when creating PHP web pages. The attacker can now forge his input to access the files on the computer that he wants, a common example is:
Please note that while this is a potentially severe attack, it does not give you root access, and files that are unavailable to the httpd (for Apache web servers) user, are unavailable to you as well.
How to avoid this?
In order to avoid LFIs, you have to validate the language variable. There are overwhelmingly many ways to do this. A simple example would be to only include files whose names contain 3 or less characters:
<?php $language = $_GET['language']; if(strlen(“$language”) < 4) include($language); ?>
This is nice, but the best way of doing it would be to add all of the valid values of the language variable in an array, and check if the value passed in the address bar matches one of the values in the array.
<?php $available_languages = array('eng', 'nor', 'ger'); $language = $_GET['language']; if(in_array($language, $available_languages)) include($language); ?>
This will stop people from accessing files that they do not have access to.
Safer code == Safer communities.
If you’ve got further questions, send us an email at firstname.lastname@example.org!
By: Håkon Vågsether