Jump to content

sharing tips on handle remote file inclusion


orange08

Recommended Posts

hi, guys i would like to know how you guys prevent this remote file inclusion in your php site? i did read some prevention way online, but still read some others that claim that those are actually not enough to prevent it, so just wanna to know how you guys deal with it...

 

thanks for sharing!

Link to comment
Share on other sites

It isn't all that hard. It isn't like the vulnarability magically happens. For RFI to occur the code has to allow a file inclusion which is in some way affected by user input. So, if you had something like this

include('myfile.php');

there is little to no risk as the include file is hard coded (see note at end).

 

However, if you had something like

$page = $_GET['page'];
include($page.'.php');

 

That is trouble waiting to happen. Whenever there is a need to use user input to decide on an include page it should ALWAYS be validated. If for instance you know that the $page value will only consist of three possibilities you could test the value against a white list of those values. If the passed value is not in that list have error handling or choose a default.

$pages = array('pageone', 'pagetwo', 'pagethree');
$page = $_GET['page'];
if(!in_array($page, $pages) { $page = $pages[0]; }
include($page.'.php');

Of course, the actual implementation could be more complex than a simple hard coded list. But, you should still have some way to validate that the values being passed are what you expect. The bottom line is NEVER trust anything the user sends you. For example, one common misconception I see is that POST data from a select list doesn't need to be validated because the user can only select a value from that list. That's not true, and again, should always be validated.

 

Regarding the previous statment that a hard-coded include is relatively safe, there are instances where it could be unsafe. But again, they are easily mitigated by a little thought. An example would be where the include() is on a page which itself is included so that the path to the include file is relative to the parent script. It would be possible to have the page include a file with the same name if it was accessed directly. But, that would only be if the user has the ability to upload a file to that specific path relative to the calling page. Some basic good file file structure would prevent this possibility.

Link to comment
Share on other sites

 

Regarding the previous statment that a hard-coded include is relatively safe, there are instances where it could be unsafe. But again, they are easily mitigated by a little thought. An example would be where the include() is on a page which itself is included so that the path to the include file is relative to the parent script. It would be possible to have the page include a file with the same name if it was accessed directly. But, that would only be if the user has the ability to upload a file to that specific path relative to the calling page. Some basic good file file structure would prevent this possibility.

 

sorry, not too understand with this part...can give example? thanks!

Link to comment
Share on other sites

Let's assume you have the following directory structure and files.

 

ROOT/
  - index.php
ROOT/USER_FILES/
  - uploader.php
ROOT/INCLUDES/
   - foobar.php[code]

The application allows users to create their own personal folder in the "USER_FILES" directory to put their personal files. Now, let's assume that index.ph and uploader.php have content such as follows:

index.php
[code]include('USER_FILES/uploader.php');

 

uploader.php

include('INCLUDES/foobar.php')

 

When index.php is called it will include uploader.php. Then the include is called in uploader.php the path is relative and it will be relative from the parent script. So the path 'INCLUDES/foobar.php' will point to the intended file as expected.

 

OK, there are problems with that structure above. Let's suppose a user creates their personal folder and names it 'INCLUDES' (ROOT/USER_FILES/INCLUDES). Then the user creates a file called foobar.php with malicious code. If the user can then directly call the uploader file, when it sees include('INCLUDES/foobar.php') it will be relative to the uploader.php file since it is the parent script and it will then include the malicious file the user created and uploaded.

 

Now, all of this assumes that the developer did a LOT of things wrong. A couple are:

- User files should be stored in a protected area outside of any application files and definitely not in a web accessible directory.

- If a file is only supposed to be included by another file (such as uploader.php in the example above) there should be some code at the top of the script to prevent direct running of the file and/or put in a directory that is not web accessible

Link to comment
Share on other sites

Let's assume you have the following directory structure and files.

 

ROOT/
  - index.php
ROOT/USER_FILES/
  - uploader.php
ROOT/INCLUDES/
   - foobar.php[code]

The application allows users to create their own personal folder in the "USER_FILES" directory to put their personal files. Now, let's assume that index.ph and uploader.php have content such as follows:

index.php
[code]include('USER_FILES/uploader.php');

 

uploader.php

include('INCLUDES/foobar.php')

 

When index.php is called it will include uploader.php. Then the include is called in uploader.php the path is relative and it will be relative from the parent script. So the path 'INCLUDES/foobar.php' will point to the intended file as expected.

 

OK, there are problems with that structure above. Let's suppose a user creates their personal folder and names it 'INCLUDES' (ROOT/USER_FILES/INCLUDES). Then the user creates a file called foobar.php with malicious code. If the user can then directly call the uploader file, when it sees include('INCLUDES/foobar.php') it will be relative to the uploader.php file since it is the parent script and it will then include the malicious file the user created and uploaded.

 

Now, all of this assumes that the developer did a LOT of things wrong. A couple are:

- User files should be stored in a protected area outside of any application files and definitely not in a web accessible directory.

- If a file is only supposed to be included by another file (such as uploader.php in the example above) there should be some code at the top of the script to prevent direct running of the file and/or put in a directory that is not web accessible

 

but, if my site didn't allow user to create folder and upload their files, then no such worry, right?

Link to comment
Share on other sites

In addition to what mjdamato has posted, there is also an option allow_url_fopen in your php.ini file that if disabled will not allow functions like include(), require(), file_get_contents() and so on to be able to retrieve data from remote locations.

Link to comment
Share on other sites

but, if my site didn't allow user to create folder and upload their files, then no such worry, right?

 

I'm not saying that is the only risk. I was only giving one possible risk. All it takes is a little thought to look at how your files are used and to prevent malicious use.

Link to comment
Share on other sites

In addition to what mjdamato has posted, there is also an option allow_url_fopen in your php.ini file that if disabled will not allow functions like include(), require(), file_get_contents() and so on to be able to retrieve data from remote locations.

 

yup, i did read it online and set it already...

how about this:

Here we check our query string for http://, https:// or ftp://

 

RewriteCond %{QUERY_STRING} (.*)(http|https|ftp):\/\/(.*)

 

If you are using this rewrite within a .htaccess all you have left is to deny access from all matching requests.

 

RewriteRule ^(.+)$ - [F]

 

If you have access to your vhost you could also log those requests like this:

 

<IfModule mod_rewrite.c>

  RewriteEngine on

  RewriteCond %{QUERY_STRING} (.*)(http|https|ftp):\/\/(.*)

  RewriteRule ^(.+)$ - [env=rfi:true]

</IfModule>

CustomLog /path/to/logs/rfi.log combined env=rfi

 

You will also have to deny access from requests that have been caught by the above rewrite

 

Deny from env=rfi

 

get from http://www.phpfreaks.com/tutorial/preventing-remote-file-include-attacks-with-mod-rewrite

 

as i don't understand the code, so don't know which part should be modified and put in my .htaccess...can give a bit guidance here?

 

thanks!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.