The Joomla!® Community Magazine

The prefix has nothing to do with telephony

Written by Nicholas K. Dionysopoulos | Sunday, 01 August 2010 18:21 | Published in 2010 August
  • Print
  • Email
  •  
Level of Difficulty:Intermediate When dealing with website security, most web masters think only about fending off potential attacks. However, we are all human. No matter how hard we try, some of the attacks will make it through, and hit our site. Our concern should be making sure that these attacks never cause any real harm to our site. We'll start covering our bases from... the database! In this issue we'll see some working, real-world examples of security measures based on that concept, which take a minimal amount of time and skills to apply to your own site. But, first, what has the database to do with security and your site surviving hacking attempts anyway?
The prefix has nothing to do with telephony

The Achilles’ heel

Given that the majority of attacks which might get through any countermeasure are going to be SQL injection (a.k.a. SQLi) attempts, our first line of defense should be the database. Some dry theory should help us appreciate the importance of this. There is a concept in epidemiology called “homogeneous populations”. This is a fancy term, which stands for many different members of a same group sharing a common characteristic. In this context, homogeneous populations are prone to be wiped out by a single threat, if that threat uses this common characteristic to gain leverage against each of the members. In other words, if you look alike to your neighbours, you're in deep trouble!

Believe it or not, Joomla! sites consist of a homogeneous population, vulnerable to severe threats! No, this is not a problem in Joomla!'s design, rather than a misunderstanding of how Joomla! is supposed to work. I am talking about the database table prefix, which defaults to jos_. Most SQLi attacks I've seen “in the wild”, take for granted that your site is using the default setting for the database table prefix to deliver their malicious actions against you. Sadly, they are right. Even though jos_ is a default value meant to be changed during installation, it rarely is. As a result, this benevolent default setting proves to be the Achilles' heel of Joomla!. But, really, has it got to be that way with your site?

Thinking before clicking

Thankfully, the answer to my last rhetorical question is a solid and loud “No, sir!” You can prevent being part of the “homogeneous population” of Joomla! sites, if only you take care during installation. This is extremely easy. The solution is found in the fourth page of Joomla!'s installation, titled “Database Configuration”. Click on the “Advanced settings” header and locate the “Table Prefix” field. Now all you have to do is pick a good new database table prefix.

There are no general rules about picking a database table prefix. Ideally, it should be something hard to guess, contain only alphanumeric characters, not too big, not too small and end with an underscore. If this sounds complicated, I will agree with you. My general rule of thumb is: pick three random lower case letters (a-z, no accented or international characters, please) and add an underscore. For example, aow_ is a good prefix, but aøw_, αοβ_ or somethingwaytoolongtobepractical_ is not. That's much simpler, right?

If you came late to this party...

...you are already using the default jos_ prefix. Don't fear and don't despair! We can fix that, with a small PHP script, courtesy of your friendly neighbourhood developer — that's yours truly. Before you proceed, do note that modifying your site's database can be potentially dangerous. You will be playing with live fire here, so there's no room for error. Practise those changes on a local server or a development site first. Keep notes of what you do. In any case, before you attempt any change whatsoever, remember practicing the three basic rules of being a web master: backup, backup, and — most importantly — backup! That said, in order to change your database table prefix, create a file named rename.php in your site's root with the following contents:

<?php
$new_prefix = 'new_';
require_once 'configuration.php';
$config = new JConfig;
$con = mysql_connect($config->host, $config->user, $config->password);
if(!is_resource($con)) die('Error connecting to db');
$test = mysql_select_db($config->db, $con);
if($test===false) die('Error connecting to db');
$prefix = $config->dbprefix;
$sql = "show tables where `Tables_in_{$config->db}` like '{$prefix}%'";
$res = mysql_query($sql);
while($row = mysql_fetch_array($res))
{
$old = $row[0];
$new = $new_prefix . substr($old, 4);
$temp = mysql_query("RENAME TABLE `$old` TO `$new`");
if($temp === false) die(mysql_error());
mysql_free_result($temp);
}
mysql_free_result($res);
mysql_close($con);
echo "OK";

You have to substitute the new_ placeholder in the second line with your desired new prefix. After saving this to your site's root, run it by accessing the script with a URL like http://www.yoursite.com/rename.php and wait until it responds with an OK, usually after a couple of seconds.

At this point, the first thing you have to do is remove the rename.php script from your site's root. Then, edit the configuration.php file and find the line starting with var $dbprefix. It should look like this:

var $dbprefix = 'jos_';

Replace the old jos_ prefix with your new prefix, i.e. the one you used in the second line of your rename.php script. If your new prefix is new_, this line should now read:

var $dbprefix = 'new_';

Save the file and you're good to go! You've just changed your database table prefix and you're one step closer to fending off attacks by potential hackers.

Honey, I’m already on my way home...

Yes, we've ran out of space for this issue, but worry not! There are quite a few more site security articles in this on-going series. In the next issue, we're going to talk about another practical security tip which has to do with your database. I won't say more, but I'll give you some hints. I've talked about it in my last article, and it's always there when you install Joomla! on a server. I know that most of you must have figured it out by now.

Until our next issue, take care and be safe!

Tagged under Administrators Toolkit

Social sharing is caring ;)

Nicholas K. Dionysopoulos

Nicholas K. Dionysopoulos

A Mechanical Engineer turned web developer I am mostly known as the lead developer of Akeeba Backup, the leading open source backup solution for Joomla!. When not working on my flagship software I enjoy squashing Joomla!bugs, writing articles about Joomla!, helping out with this magazine and playing the guitar.

Leave a comment

Make sure you enter the (*) required information where indicated.

[b] [i] [u] [s] [url] [quote] [code] [img]   

Comments (39)

  • avatar
    • 0
    • 0
    John Pitchers

    Hi Nicholas, Great tip. I've always left it as jos_ as I figured it could cause problems if I changed it. Will be sure to do this in all my installs from now on.
    Good work with Akeeba.

  • avatar
    • 0
    • 0
    Detlef Volmer

    This is a great little script. Thank you for that. It took me less than a minute to resolve this issue on one of my live sites.

  • avatar
    • 0
    • 0
    Francesco Abeni

    Nicholas, i already appreciated your post about permissions and this is another very neat piece of information. Easy to read, clear to understand.
    Congratulations.

  • avatar
    • 0
    • 0
    Bo Astrup

    Many thanks Nicholas, this is extremely helpful to all those people who use Fantastico, SimpleScripts or other "one-click" installers as they don't allow users to change the prefix during install.

  • avatar
    • 0
    • 0
    Dan Chay

    !!! Thank you.

  • avatar
    • 0
    • 0
    Nicholas K. Dionysopoulos

    Thank you guys for your positive feedback! I will be writing more articles in this security series over the next few JCM issues.

  • avatar
    • 0
    • 0
    mandville

    isnt that script missing a cosing tag?

  • avatar
    • 0
    • 0
    Herman Peeren

    Thank you, Nicholas. All security measures are helpful to make it more secure. Specially because most attacks are done by scripts, that hardly look any further than the default settings. Of course, once a real person starts using some sql-injection, then a show tables command unveils all MySql-table names. Security is a never-ending story.

  • avatar
    • 0
    • 0
    Brian Teeman

    Thanks Nicholas

    I just wish Joomla installation did not hide the ability to set the prefix in the advanced settings.

    It would be so easy to move it from the hidden advanced tab but it never gets done, even with joomla 1.6 ;(

  • avatar
    • 0
    • 0
    Paulette Marzahl

    Thanks Nicholas!!

  • avatar
    • 0
    • 0
    Steve

    Hi Nicolas,

    Thanks for a very useful article and solution with supporting code.

    You have a great delivery style on tech/code issues on the forums, people.joomla.org and now here in the community magazine (which is really well produced). As a none code savvy joomla abuser (I mean user), I really appreciate you taking time to share your knowledge - in such an easy to digest and understandable manor.

    It's people like you, that put the '!' in joomla! and it's community.

    Thanks for a great article, can't wait for the next issue. :)

  • avatar
    • 0
    • 0
    Herman Peeren

    Thank you, Nicholas. All measures can help to make it a bit more secure. Especially because most attacks are done by scripts, that hardly look any further than the
    default settings.

    Unfortunately it only helps a little bit: once a real cracker starts using some sql-injection, then she/he just has to add union select table_name from

    information_schema.tables (or some variations on that to adjust the column names and number) to the injected sql to unveil all MySql-table names! When a sql-injection

    is possible, you have a problem. Best is to fix the problem and not just rely on temporary obfuscation-methods as described in your article. Unsanitized user input should

    never be allowed in the code.

    So, stay alert. Security is a never-ending story.

  • avatar
    • 0
    • 0
    Miguel Corsi

    Excellent article! Very clear and easy-to-follow instructions for a newbie like me.

    I am not sure, but it looks like my site is running faster after the changes. Is it possible that the original extention was a "little" corrupted and with this fresh new one performance has improved?

  • avatar
    • 0
    • 0
    Herman Peeren

    The prefix-change is probably hided so far away in the settings, because it was not meant as a security-measure: AFAIK it was made to give the possibility to use several Joomla!-installations in one database.

  • avatar
    • 0
    • 0
    Nicholas K. Dionysopoulos

    @Mandville No, the closing tag is optional (a little known fact!) and I just chose to skip it.
    @Brian I'll top that and I'll become a heretic. I propose that the default value of the prefix should be three random letters on each new installation.
    @Steve I am humbled and honoured by your positive feedback. Thank you!
    @Herman You are two issues ahead :D I'm writing an article on .htaccess which, among other things, allows you to dodge the most common SQLi tricks, like UNION SELECT. And, yes, the prefix was meant for multiple installations, but it became very evident that it doubles as a first line of defense. IMHO, it should be treated as a security feature.
    @Paulette, @John Thank you for your kind words!

  • avatar
    • 0
    • 0
    Nicholas K. Dionysopoulos

    @Miguel The tables might have had a lot of unused space, which makes accessing them slow. When you renamed the tables MySQL "cleared the house" for you. You can do the same thing manually, through phpMyAdmin, by selecting your site's tables and selecting Optimize from the "With selected:" menu on the bottom of the page.

  • avatar
    • 0
    • 0
    Thomas

    Thank you for this. The script you included worked like a charm. Though this is just a minor fix really.

    If a hacker really wants to mess up your site something like this won't stop them and they'll just find another way.

    But every bit helps!

  • avatar
    • 0
    • 0
    leo lammerink

    Thanks for this article Nicholas. A script exists to do this since april and I have tested this on a couple of installs and it works well. That script also takes care of the correct permissions. You might want to check it out?

    Change Database Prefix

    http://extensions.joomla.org/extensions/tools/database-tools/12150

  • avatar
    • 0
    • 0
    Toé

    Nice article! I posted the french version here http://bit.ly/aTtWwe

  • avatar
    • 0
    • 0
    GuidedHelp.net

    Rather than having the standard jos_ prefix within the Joomla Setup configuration screens I think it should be automatically randomized and give you the option to change it.

  • avatar
    • 0
    • 0
    Luis Pedro Pérez

    That script gave me a couple of warnings:
    Warning: mysql_free_result() expects parameter 1 to be resource, boolean given in C:wampwwwjoomlarename.php on line 18
    but after it all gave me an OK and it worked like a charm! tnx!

  • avatar
    • 0
    • 0
    Sarah Bell

    Excellent tip Nicholas! Very straight forward instructions and no dramas from my end. Thank you very much. btw Akeeba Backup Rocks!!

  • avatar
    • 0
    • 0
    Phil

    I followed these instructions but now I get an error saying Database Error: Unable to connect to the database:Could not connect to MySQL

    In the myphpadmin section I see the tables with the new prefix and the configuration.php file has the new prefix added. There was tables with bak_ prefix which I deleted to see if that was the problem but it never helped.

    Any ideas?

  • avatar
    • 0
    • 0
    Phil

    In reply to my last comment.

    I generated a new db password then changed the file permissions of the configuration.php file,
    then changed the var $password to the new db password. Finally chnaged the config file permissions back to 444, is this correct permissions?

    Everything seems to be working fine now.

    Thanks

  • avatar
    • 0
    • 0
    Sarah Bell

    Hi there,

    After a few days I got the same MySQL error as Phil.

    I have changed the permissions of the configuration.php file to 644 and the site worked for a little bit, but now I'm back to square one. I'm also running a Virtuemart shop on the site and was not able to access any of the category listings... it was just lagging when you clicked on a category.

    Any suggestions as to what I can do? Your help is really appreciated :)

  • avatar
    • 0
    • 0
    Sarah Bell

    Ha! It's working now... go figure???

    Any suggestions as to how I can resolve this issue if it comes up again??

    Cheers!

  • avatar
    • 0
    • 0
    Nicholas K. Dionysopoulos

    Phil,

    If your host is running suPHP, giving very "wide" permissions (i.e. 0777 or even 0755) might cause the PHP file to not be parsed, as if it wasn't there, for security reasons. Changing the permissions to 0644 or 0444 is adequate to resolving this issue, as you seem to have discovered yourself.

  • avatar
    • 0
    • 0
    Nicholas K. Dionysopoulos

    Samson,

    This is an ongoing series, covering all the basic security practices you can apply on your site. The golden rules, however, is to update every extension you use on your site (even your template!) regularly and to always have an up-to-date and tested backup in case things go awry. Everything else you do is not going to give you any protection if you don't follow these basic rules.

  • avatar
    • 0
    • 0
    Nicholas K. Dionysopoulos

    Sarah, this sounds like an overcrowded server. Most shared hosts house an inhuman number of sites (2,000-3,000) on a single physical server. The sites have to struggle to get resources necessary to run. If many of the sites ask for lots of resources, the whole server lags and you experience what you describe.

    The only workaround is to switch to a performance tuned hosting solution. I can't really suggest hosts through the JCM, but if you take a look on AkeebaBackup.com's forum it's more than easy to figure out which is the host I suggest to users who ask for my advice :)

  • avatar
    • 0
    • 0
    Sarah Bell

    Thanks for the tip Nicholas, I'll check out the Akeeba Backup forum.

    I'm even starting to have trouble with user registrations now, and I didn't before... always some puzzle to solve.

    Really appreciate your time and feedback :)

  • avatar
    • 0
    • 0
    pepperstreet

    This little tool works in legacy mode as far as i know... just remember i used it some time ago.

    DOWNLOAD
    http://joomla.daveslist.co.nz/index.php?option=com_content&task=view&id=19& Itemid=35
    INFO
    http://joomla.daveslist.co.nz/forum/viewtopic.php?f=7&t=41

  • avatar
    • 0
    • 0
    Tom D

    Thank You Nicholas! Very helpful articles.
    I ran your rename.php against my jos_ tables and it did work.
    I had just updated to 1.5.22.
    I got a list of these though:
    Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in /home/wisdomof/public_html/rename.php on line 18

    Apparently one for each table in my db. Gave me a bit of a start but I up loaded my changed configuration.php file and all was well.

    I'm not the low hanging fruit I was a little while ago.

    BTW I think you have a good clear writing style. You make these things really pretty understandable. Thank You Again
    Tom

  • avatar
    • 1
    • 0
    JD-Webdesign

    Hi,

    Great script but after renaming, I have all my data tables in double.

    Can I delete the ones with the jos_ prefix ?

    Thanks,

    JD

  • avatar
    • 0
    • 0
    yo

    I have tried and not runs. I am using joomla 1.5.23

    Display error on line 18:

    PHP Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in /usr/home/xxxxxxxxxxxxx.com/web/rename.php on line 18

  • avatar
    • 0
    • 0
    KriZa

    Great Script!
    a little update on line:

    Code:
    $new = $new_prefix . substr($old, 4);

    to:

    Code:
    $new = $new_prefix . substr($old, strlen($prefix));


    now you're able to change already updated prefixes of variable length

  • avatar
    • 0
    • 0
    Techna

    I have a joomla 1.7 website that was installed through go daddy. It has jos-....can I change it the same way as shown here ?

  • avatar
    • 0
    • 0
    Techna

    I have a joomla 1.7 website that was installed through go daddy. It has jos-....can I change it the same way as shown here ?

Powered by Compojoom comment
English

Contribute An Article

The Administrators Toolkit covers subjects of interest to website administrators.

If you would like to contribute an article in an upcoming issue, visit the Become An Author area for more information.

Contributing Authors