das 'komplett' zu übernehmen, fehlt mir leider die Zeit.
Ich habe aber mittlerweile herausgefunden WIESO das Problem auftaucht.
Scheinbar wurde für QContact an einigen Stellen sehr viel Source-Code aus der Original-Joomla-Contact Komponente kopiert.
Der Code ist fast gleich.
Das bedeutet, das auch das Model von Joomla ( components\com_contact\models\category.php ) per se für SQLi anfällig ist !! 
PHP-Code:
_getContactsQuery( &$options ) { ..
$orderBy = @$options['order by'];
..
$query = 'SELECT ' . $select .
...
($groupBy ? ' GROUP BY ' . $groupBy : '').
($orderBy ? ' ORDER BY ' . $orderBy : '');
}
Der Unterschied liegt darin, dass die View von Joomla die Filter-Vars so ermittelt:
PHP-Code:
$filter_order = JRequest::getVar('filter_order', 'cd.ordering', '', 'cmd');
$filter_order_Dir = JRequest::getVar('filter_order_Dir', 'ASC', '', 'word');
...
$options['order by'] = "$filter_order $filter_order_Dir, cd.ordering";
wohin gegen die QContacts Komponente dies so macht:
PHP-Code:
$filter_order =$mainframe->getUserStateFromRequest('com_qcontacts.filter_order'.$categoryId, 'filter_order', 'cd.'.$pparams->get('default_ordering','ordering'), '', 'cmd');
$filter_order_Dir =$mainframe->getUserStateFromRequest('com_qcontacts.filter_order_Dir'.$categoryId, 'filter_order_Dir', 'ASC', '', 'word');
...
$options['order by'] = "$filter_order $filter_order_Dir, cd.ordering";
Da das Model "sich nicht selbst vor Injection schützt", sondern sich auf die View verlässt, kann man dann den Code einschleußen.
Zu untersuchen wäre noch warum getUserStateFromRequest dies nicht erledigt ( Verwendung der Methode usw. ).
( an $mainframe sieht man, dass man an der Komponente so einiges Umstellen müsste )
Gruß
Micha
PS.:
in Joomla 2.5 ist das Problem NICHT vorhanden. Dort wird im Model geprüft ob der übergebene Wert in einer definierten Liste ( Spaltennamen, Ordertypes,.. ) enthalten ist.
( in Docu steht since 1.6 )
z.B.
PHP-Code:
$config['filter_fields'] = array(
'id', 'a.id',
'name', 'a.name',
'con_position', 'a.con_position',
'suburb', 'a.suburb',
'state', 'a.state',
'country', 'a.country',
'ordering', 'a.ordering',
'sortname',
'sortname1', 'a.sortname1',
'sortname2', 'a.sortname2',
'sortname3', 'a.sortname3'
);
Dies hätte ich schon im Code für 1.5 so erwartet....
Lesezeichen