8 minutes reading time (1562 words)

How off-line is Joomla!'s off-line mode?

How off-line is Joomla!'s off-line mode?

Joomla!’s temporary off-line mode is a very handy option to temporarily take your site down while performing maintenance —e.g. updating the Joomla! core or an extension— and is even suggested by the official documentation for the unfortunate time that your site has been compromised. However, is this really off-line, or are there any pitfalls you should be aware of?

As you might have guessed from the title, the off-line mode is not so off-line as you would think it is. As a matter of fact, the off-line mode is a magic trick, performed like any illusionist would have done. While your site works normally below the hood —component running and plugins executing— Joomla! performs a magic trick just before it sends the page to the browser, swapping the real page with the off-line system template. It is the very reason why you can type in https://www.joomla.org?tmpl=offline in your browser bar and see the official Joomla! site being apparently off-line when it’s not. Let’s see how Joomla! performs this class act of illusionist trick, the implications and a viable workaround for truly taking your site off-line in the unlikely case of an emergency.

Dissecting a magic trick

Joomla! is in fact a PHP framework with several “applications” installed out-of-the-box. The front-end part of your site is one of them. Each application inherits the abstract JApplication class. For the front-end application, the concrete implementation of JApplication is called JSite and it can be found in the includes/application.php file. The only reference to the off-line mode in there is in the render() method, where you see something interesting and disturbing: Joomla! checks if you have set your site in off-line mode just before it renders the template. If your site is off-line and it is trying to serve an HTML page and there is no user with back-end access logged in, Joomla! will load the offline.php template file instead of the regular index.php.

All right, hold on a moment. When does the render() method gets called? The answer is in the main index.php file found in your site’s root. The call to $mainframe->render() ($mainframe being a global variable which contains the JSite object) is the second to last statement in that file. In other words Joomla! will execute all plugins, run the component and only deal with the off-line mode during the final step, just before it is ready to output the HTML page to the browser. The JSite::render() method also tells us that only the HTML mode is affected by the off-line mode. And this, my friends, may have chilling effects on your site...

The chilling effects

Think for a minute when and why you might be using the off-line mode. For starters, when you are building a website and don’t want the world to see it just yet. In that case the off-line mode is fine, as it merely hides the user-viewable content from random web visitors. In that sense, the off-line mode works just fine. But this is not the only, or even the most frequently used, case.

Remember the link I gave you in the introduction of the article, mentioning what you should do when your site gets hacked? The official documentation is to use the off-line mode immediately after being hacked. BIG MISTAKE! Most compromised sites happen because a resourceful cracker found a blind SQL injection vulnerability or a direct file upload loophole on your site.

In the case of an SQL injection vulnerability, a cracker appends an SQL statement of his liking to a URL on your site, directly executing his malicious commands against your site’s database. The premise of this attack is that the vulnerable component parses the query parameters the cracker sends to it. Guess what? Even in off-line mode, you are still susceptible to SQL injection attacks against a vulnerable component. Why? Because the component will execute, but you will just not see its output. You are off-line and you’re still being hacked. Checkmate.

In the case of a direct file upload, the cracker uploads one of the C99-variant “root” scripts somewhere on your site, making use of a vulnerable component. The root script executes outside Joomla!, so even if you take the site off-line the hacker will still be able to use it. Let’s say you try to wise up, find that script and delete it. Ha! You beat the cracker... not. When he discovers that his script is gone, he can try to perform the direct upload again. Since the vulnerable component keeps on executing, despite not being visible, he can still upload the root script and completely own your site. Two points for the cracker, desperation for the site owner.

The bottom line is this: The off-line mode can’t and won’t protect you against a cracker.

My Kung-Fu is stronger than yours

You should have known by now. For every problem that gets in my way, I find a solution, document it and share it with the rest of the world. There is a viable workaround to completely taking your site off-line, as long as you are running Apache or any other server which supports .htaccess files and mod_rewrite. This pretty much means that it will work on all servers except most IIS installations. The idea is that we want only ourselves to have access to the site, showing a static HTML page to other visitors and the cracker, effectively outsmarting him in his own game.

The first thing you need is your public IP address, i.e. the IP used by your Internet connection. This can be usually found in your router’s connection information page and it has the form of 123.123.123.123, that is four numbers separated by dots. If you have no idea, just visit www.WhatsMyIP.org. Your IP is shown in gigantic font size on the top of the page. Note it down. For this example I am going to use the fake IP address 123.123.123.123. You also need an HTML file to show to your visitors, as we will not be using Joomla!'s off-line message any more. You can create one with any capable tool, i.e. Kompozer. You can use CSS and images if you’d like. I’ll pretend that you have created a file named offline.html and placed it in your site’s root.

Next up, you’ll create a plain text file with the following contents and upload it to your site’s root as .htaccess, overwriting your old .htaccess:

RewriteEngine On
RewriteBase /$rewrite_base
RewriteCond %{REMOTE_HOST} !123\.123\.123\.123
RewriteCond %{REQUEST_URI} !offline\.html
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.bmp|\.swf|\.css|\.js)$
RewriteRule (.*) offline.html [R=307,L]

As you can see, there are three things to change in this file:

  1. 123\.123\.123\.123 is your IP address. All you have to do is to “escape” the dots as backslash-dot. Do not forget the exclamation mark before your IP address.
  2. offline\.html is the name of your HTML file, with the dot “escaped” as backslash-dot.
  3. offline.html is the name of your HTML file. Do not escape the dot in that last instance!

Note: If your site throws a blank page or Internal Server Error 500 upon uploading the file, replace R=307 with R (without the =307 part). This is only required on Apache 2.0 and 1.3 hosts, as these old versions do not support the R=307 "flag" in those redirection rules.

As soon as you apply this file, the following will happen. If a request comes from any IP address except your own, the visitor will be redirected to the offline.html page with a temporary redirection HTTP status code (this is what R=307 does and it’s there to keep search engines from freaking out when confronted with your off-line site). However, PNG, JPG, GIF, BMP, SWF, CSS and JS files will still be served, so that you can use such media types in the offline.html file without any problems.

You can test it very easily. When you try to connect to your site, you should see no difference. If you use a device connected to the Internet from a different router, e.g. a mobile device connected to the Internet over its 3G connection, you should see the contents of the offline.html page. Victory is yours! You can now fix a hacked site without risking the cracker undoing your fixes while you’re working.

Can Joomla! be improved?

Yes and no. For starters, the method I proposed is a simple workaround to a problem, it's not a solution. It works only on 60% of hosts — that's the market share of Apache servers. The other 40% can't be protected using this method. So, no I don't consider that Joomla! is at fault for not using a method like mine in its core. It is supposed to be a versatile CMS, being able to run on pretty much any kind of server.

However, there is something which can be done. We need to move and adjust the off-line check in index.php. If the site is in off-line mode, there is no logged in Super Administrator user and the request doesn't have to do with a Super Administrator trying to log-in, do not run the application. Just show the off-line page. In any other case (e.g. in off-line mode, with a Super Administrator logged in) just run the application. That would be the simplest modification in the world and would work wonders on Joomla! security. Anyone interested in "adopting" this idea and turning it into a patch?

0
Post your Haiku here for February 2011
Good Resources for Joomla! Beginners
 

Comments

Already Registered? Login Here
No comments made yet. Be the first to submit a comment

By accepting you will be accessing a service provided by a third-party external to https://magazine.joomla.org/