The implementation of the ORDER BY
SQL statement in Zend_Db_Select
of Zend
Framework 1 contains a potential SQL injection when the query string passed
contains parentheses.
For instance, the following code is affected by this issue:
$db = Zend_Db::factory( /* options here */ );
$select = $db->select()
->from(array('p' => 'products'))
->order('MD5(1); drop table products');
echo $select;
This code produce the string:
SELECT "p".* FROM "products" AS "p" ORDER BY MD5(1);drop table products ASC
instead of the correct one:
SELECT "p".* FROM "products" AS "p" ORDER BY "MD5(1);drop table products" ASC
The SQL injection occurs because we create a new Zend_Db_Expr()
object, in
presence of parentheses, passing directly the value without any filter on the
string.
We fixed the issue in the Zend_Db_Select::order()
function using a more
granular regular expression to match only SQL functions in an ORDER BY
statement, such as ORDER BY ABS("zfproducts"."product_id")
.
The new regular expression is '/^[\w]*\(.*\)$/'
instead of the previous
'/\(.*\)/'
. This change fixes the issue, filtering the input using quotes for
the previous attack.
The previous SQL example with the fix is rendered in the correct way:
SELECT "p".* FROM "products" AS "p" ORDER BY "MD5(1);drop table products" ASC
The patch is available starting in Zend Framework 1.12.7.
This SQL injection attack does not affect Zend Framework 2 versions because the
implementation of Zend\Db\Sql\Select::order()
does not manage parenthetical
expressions.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
Released 2014-06-12
Have you identified a security vulnerability?
Please report it to us at zf-security@zend.com