6 min read

Introduction

There’s no such thing as a completely secure system. No matter how many precautions we take and how many times we verify our design and implementation, we will never be able to guarantee that we have created a truly secure Joomla! extension. Why not? This is because it is not possible to be prepared for every potential vulnerability.

Common Weakness Enumeration (CWE) is a project dedicated to generating a formal categorization and identification system of security vulnerabilities. CWE published a list of the top 25 security weaknesses, which were selected on the basis of their frequency and consequences. This list includes some of the most publicized security weaknesses, such as code injection (CWE-94) and XSS (CWE-79). When considering the security of our extensions, this list can prove useful. For information about common programming mistakes that lead to security vulnerabilities, refer to http://cwe.mitre.org/top25/.

This article includes references to the CWE weaknesses. These references are in the form of CWE IDs, that is, CWE-n. For information about a weakness, simply Search By ID on the CWE web site. These references are intended to help us better understand the weaknesses, the risks associated with the weaknesses, how the risks can be reduced using the Joomla! framework, and the suggested CWE mitigations.

Something we should consider is the ramifications of security flaws. Whichever way we look at this, the answer always involves financial loss. This is true even of non-profit organizations. If a web site is attacked and the attacker managed to completely obliterate all the data held on that web site, it will cost the owner’s time to restore a backup or replace the data. OK, it may not seem like a financial loss because it’s non profit. It is a wastage of time if the web site owner spends two hours to restore his or her data, as those two hours could have been used elsewhere.

For commercial web sites, the potential for financial loss is far more obvious. If we use a bank as an example, a security flaw could enable an attacker to transfer money from the bank to his or her own (probably untraceable) account. In 2004, the Internet bank Cahoot suffered a security flaw enabling any existing customer access to other customers’ accounts. Cahoot did not suffer any obvious financial loss from the security flaw and they claimed there was no risk of financial loss. However, the customers’ confidence in Cahoot was inevitably lost. This loss of confidence and bad press will certainly have affected Cahoot in some way. For example, some potential customers may have decided to open an account with a rival bank because of concerns over how secure their savings would, or would not, be with Cahoot. For more information, refer to http://news.bbc.co.uk/1/hi/business/3984845.stm.

From the perspective of an extension developer, we should reflect on our moral duty and our liability. Disclaimers, especially for commercial software, do not relinquish us of legal responsibility. We should always try to avoid any form of litigation, and I’m not suggesting that we run to Mexico or our closest safe haven. We should take a holistic approach to security. We need a complete view of how the system works and of the various elements that need to be secure. Security should be built into our extension from the requirements gathering stage through to the ongoing system maintenance.

How we do that depends on how we are managing our project and what the security implications of our extension are. For example, a shopping cart component with credit card processing facilities will require far greater attention to security than a content plugin that converts the occurrences of 🙂 to smiley face images. Irrespective of the way we choose to manage the risks of weaknesses, we should always document how we are circumventing security threats. Doing so will make it easier to maintain our extension without introducing vulnerabilities. Documentation also provides us with proof of prudent risk management, which can be useful should we ever be accused of failing to adequately manage the security risks associated with our software.

This is all starting to sound like a lot of work! This brings us back to the ramifications of vulnerabilities. If on the one hand, it costs us one extra month of development time to produce a piece of near-secure software. And on the other hand, it costs us two months to patch a non-secure piece of software and an incalculable amount of damage to our reputation. It is clear which route we should favor!

Packt Publishing offers a book that deals specifically with Joomla! security. For more information, refer to http://www.packtpub.com/joomla-web-security-guide/.

Writing SQL safe queries

SQL injection is probably the most high profile of all malicious web attacks. The effects of an SQL injection attack can be devastating and wide ranging. Whereas some of the more strategic attacks may simply be aimed at gaining access, others may intend on bringing about total disruption and even destruction. Some of the most prestigious organizations in the world have found themselves dealing with the effects of SQL injection attacks. For example, in August 2007 the United Nations web site was defaced as a result of an SQL injection vulnerability. More information can be found at http://news.bbc.co.uk/1/hi/technology/6943385.stm.

Dealing with the effects of an SQL injection attack is one thing, but preventing them is quite another. This recipe explains how we can ensure that our queries are safe from attack by utilizing the Joomla! framework. For more information about SQL injection, refer to CWE-89.

Getting ready

The first thing we need is the database handler. There is nothing special here, just the usual Joomla! code as follows:

$db =& JFactory::getDBO();

How to do it…

There are two aspects of a query that require special attention:

  • Identifiers and names
  • Literal values

The JDatabase::nameQuote() method is used to safely represent identifiers and names. We will start with an easy example, a name that consists of a single identifier.

$name = $db->nameQuote('columnIdentifier');

We must take care when dealing with multiple-part names (that is, names that include more than one identifier separated by a period). If we attempt to do the same thing with the name tableIdentifier.columnIdentifier, we won’t get the expected result! Instead, we would have to do the following:

// prepare identifiers
$tableIdentifier = $db->nameQuote('tableIdentifier');
$columnIdentifier = $db->nameQuote('columnIdentifier');
// create name
$name = "$tableIdentifier.$columnIdentifier";

Avoid hardcoding encapsulation

Instead of using the JDatabase::nameQuote() method, it can be tempting to do this: $sql = ‘SELECT * FROM `#__foobar_groups` AS `group`’. This is OK as it works. But the query is now tightly coupled with the database system, making it difficult to employ an alternative database system.

Now we will take a look at how to deal with literal values. Let’s start with strings. In MySQL, strings are encapsulated in double or single quotes. This makes the process of dealing with strings seem extremely simple. Unfortunately, this would be an oversight. Strings can contain any character, including the type of quotes we use to encapsulate them. Therefore, it is also necessary to escape strings. We do all of this using the JDatabase::Quote() method as follows:

$tableIdentifier = $db->nameQuote('tableIdentifier');
$columnIdentifier = $db->nameQuote('columnIdentifier');
$sql = "SELECT * FROM $tableIdentifier "
. "WHERE $columnIdentifier "
. ' = ' . $db->Quote("How's the recipebook going?");

The JDatabase::Quote() method essentially does the following. The exact output will depend on the database handler. However, most databases escape and encapsulate strings in pretty much the same way.

 

Original

Quoted

How’s the recipebook going?

‘How’s the recipebook going?’

LEAVE A REPLY

Please enter your comment!
Please enter your name here