Preventing Remote File Includes Attack on your Joomla Websites

6 min read

PHP is an open-source server-side scripting language. It is the basis of many web applications. It works very nicely with database platforms such as Joomla!. Since Joomla! is growing, and its popularity is increasing, malicious hackers are looking for holes. The development community has the prime responsibility to produce the most secure extensions possible. In my opinion, this comes before usability, accessibility, and so on. After all, if a beautiful extension has some glaring holes, it won’t be useable. The administrators and site development folks have the next layer of responsibility to ensure that they have done everything they can to prevent attacks by checking crucial settings, patching, and monitoring logs. If these two are combined and executed properly, they will result in secure web transactions.

The SQL Injections, though very nasty, can be prevented in many cases; but a RFI attack is a more difficult one to stop altogether. So, it is important that you are aware of them and know their signs.

Remote File Includes

An RFI vulnerability exists when an attacker can insert a script or code into a URL and command your server to execute the evil code.

It is important to note that File Inclusion attacks, such as these, can mostly be mitigated by turning Register_Globals off.
Turning this off ensures that the $page variable is not treated as a super-global variable, and thus does not allow an inclusion.

The following is a sanitized attempt to attack a server in just such a manner:

If the site in this example did not have appropriate safeguards in place, the following code would be executed:

$x0b="inx72_147x65x74"; $x0c="184rx74o154x6fwex72";
echo "c162141156kx5fr157cx6bs";
if (@$x0b("222x61x33e_x6d144e") or
$x0c(@$x0b("x73ax66x65_mx6fde")) == "x6fx6e")
echo "345a146x65155od145x3ao156";
echo "345a146ex6dox64e:x6ffx66";
exit(); ?>

This code is from a group that calls itself “Crank”. The purpose of this code is not known, and therefore we do not want it to be executed on our site. This attempt to insert the code appears to want my browser to execute something and report one thing or another:

{echo "345a146x65155od145x3ao156";}
echo "345a146ex6dox64e:x6ffx66";

Here is another example of an attempted script. This one is in PHP, and would attempt to execute in the same fashion by making an insertion on the URL:

<html><head><title>/// Response CMD ///</title></head>
<body bgcolor=DC143C>
<H1>Changing this CMD will result in corrupt scanning !</H1>
if((@eregi("uid",ex("id"))) || (@eregi("Windows",ex("net start")))){
echo("Safe Mode of this Server is : ");
if((@eregi("uid",ex("id"))) || (@eregi("Windows",ex("net start")))){
echo("Safe Mode of this Server is : ");
echo("Safe Mode of this Server is : ");
elseif(@is_resource($f = @popen($cfe,"r"))){
$res = "";
while(!@feof($f)) { $res .= @fread($f,1024); }
return $res;

This sanitized example wants to learn if we are running SAFE MODE on or off, and then would attempt to start a command shell on our server. If the attackers are successful, they will gain access to the machine and take over from there. For Windows users, a Command Shell is equivalent to running START | RUN | CMD, thus opening what we would call a “DOS prompt”.

Other methods of attack include the following:

  • Evil code uploaded through session files, or through image uploads is a way of attacking.
  • Another method of attack is the insertion or placement of code that you might think would be safe, such as compressed audio streams. These do not get inspected as they should be, and could allow access to remote resources. It is noteworthy that this can slip past even if you have set the allow_url_fopen or allow_url_include to disabled.
  • A common method is to take input from the request POST data versus a data file.

There are several other methods beyond this list. And just judging from the traffic at my sites, the list and methods change on an “irregular” basis. This highlights our need for robust security architecture, and to be very careful in accepting the user input on our websites.

The Most Basic Attempt

You don’t always need a heavy or fancy code as in the earlier examples. Just appending a page request of sorts to the end of our URL will do it.

Remember this?


Here we’re instructing the server to force our path to change in our environment to match the code located out there. Here is such a “shell”:

$file =$_GET['evil-page'];
include($file .".php");

What Can We Do to Stop This?

As stated repeatedly, in-depth defense is the most important of design considerations. Putting up many layers of defense will enable you to withstand the attacks. This type of attack can be defended against at the .htaccess level and by filtering the inputs.

One problem is that we tend to forget that many defaults in PHP set up a condition for failure. Take this for instance:

allow_url_fopen is on by default.

“Default? Why do you care?” you may ask. This, if enabled, allows the PHP file functions such as file_get_contents(), and the ever present include and require statements to work in a manner you may not have anticipated, such as retrieving the entire contents of your website, or allowing a determined attacker to break in. Since programmers sometimes forget to do proper input filtering in their user fields, such as an input box that allows any type of data to be inputted, or code to be inserted for an injection attack.

Lots of site break-ins, defacements, and worse are the result of a combination of poor programming on the coder’s part, and not disabling the allow_url_fopen option. This leads to code injections as in our previous examples.

Make sure you keep the Global Registers OFF. This is a biggie that will prevent much evil!

There are a few ways to do this and depending on your version of Joomla!, they are handled differently.

In Joomla! versions less than 1.0.13, look for this code in the globals.php

// no direct access
defined( '_VALID_MOS' ) or die( 'Restricted access' );
* Use 1 to emulate register_globals = on
* Use 0 to emulate register_globals = off
define( 'RG_EMULATION', 0 );

Make sure the RG_EMULATION has a ZERO (0) instead of one (1). When it’s installed out of the box, it is 1, meaning register_globals is set to on.

In Joomla! 1.0.13 and greater (in the 1.x series), look for this field in the GLOBAL CONFIGURATION BUTTON | SERVER tab:

Joomla! Web Security

Have you upgraded from an earlier version of Joomla!?
Affects: Joomla! 1.0.13—1.0.14


Please enter your comment!
Please enter your name here