Perhaps a slightly loud title of the article, but this question is raised.First moment
If you follow all the rules, i.e. use the internal mechanisms of Zend, prepare the parameters in the methods - then at the moment there is no information about the possibility of a sql injection. We are talking about similar structures:
$select->order($value);
Which somehow meet in practice.
Second moment
What is the salt? The fact is that even with the input of parameters to such methods without any preparation, the internal mechanisms still prepare them. But not all (and some partially) - this is what they mean.
Although we have the source code of this library, we will consider this topic as a “black box”, it will be clearer and clearer. More specifically, the MySQL adapter, the
Zend_Db_Select class (the same was tested on PgSQL)
')
Third moment
In order to conduct an injection in Zend, we need to close the previous back quote (for example, in the case of the syntax from =
select * from `table` ), or the apostrophe - (
where id = '1' ), since Zend follows the rules when specifying the parameter opens the desired "frame". In the first case, when passing to the
tab`ble input, we should have
ta``ble at the output, in the second
case : at the input
1'2 , at the output
1''2 .
Once again, we are talking about the "raw" sending data to the method.
We have three cases:
- FQ - all parameters are prepared (fully quoted)
- NQ - the data is not prepared, everything will “go away” to the database, as it was transmitted (no quoted)
- PQ - some parameters are being processed, some are not (partially quoted)
Let's go in order, in order in the syntax of SQL
1) -> from - FQ
Code:
$table = "wp_use`rs"; $select->from($table);
[queryString] => SELECT `wp_use``rs`.* FROM `wp_use``rs`
2) -> join - PQ
$table1 = 'tab`le1'; $table2 = 'tab`le2'; $key = 'i`d'; $data = 'da`ta'; $select = $db->select()->from($table1)->join($table2, $table1.'.'.$key.' = '.$table2.'.'.$key, array($data));
[queryString] => SELECT `tab``le1`.*, `tab``le2`.`da``ta` FROM `tab``le1` INNER JOIN `tab``le2` ON tab`le1.i`d = tab`le2.i`d
3) -> joinUsing - PQ
$table1 = 'tab`le1'; $table2 = 'tab`le2'; $key = 'i`d'; $column = 'c`ol\'u;m"n'; $select = $db->select()->from($table1)->joinUsing($table2, $column);
[queryString] => SELECT `tab``le1`.*, `tab``le2`.* FROM `tab``le1` INNER JOIN `tab``le2` ON `tab``le2`.c`ol'u;m"n = `tab``le1`.c`ol'u;m"n
4) -> where - NQ
$select->from($table); $value = "1)2'3 --"; $select->where($value);
[queryString] => SELECT `wp_users`.* FROM `wp_users` WHERE (1)2'3 --)
5) -> group - FQ
$table = "wp_users"; $value = 'i`d'; $select = $db->select()->from($table)->group($value);
[queryString] => SELECT `wp_users`.* FROM `wp_users` GROUP BY `i``d`
6) -> having - NQ
$table = "wp_users"; $value = 'some_count > 0); hello habr -- 10'; $select = $db->select()->from($table)->having($value);
[queryString] => SELECT `wp_users`.* FROM `wp_users` HAVING (some_count > 0); hello habr -- 10)
7) -> order - FQ
$table = "wp_users"; $value = i`d'; $select = $db->select()->from($table)->order($value);
[queryString] => SELECT `wp_users`.* FROM `wp_users` ORDER BY `i``d` ASC
8) -> limit - FQ
There is not even FQ, but simply - type conversion (to int)
$table = "wp_users"; $limit1 = '1; hello -- '; $limit2 = '2; hello -- '; $select = $db->select()->from($table)->limit($limit1, $limit2);
[queryString] => SELECT `wp_users`.* FROM `wp_users` LIMIT 1 OFFSET 2
Here -> limitPage (), similar work
9) -> union - NQ
$ db-> select + string
$table = "wp_users"; $select = $db->select()->from($table); $select2 = "select * from ta\"b'le`2"; $select3 = $db->select()->union(array($select, $select2)); $db->query($select3);
[queryString] => SELECT `wp_users`.* FROM `wp_users` UNION select * from ta"b'le`2
Summary
FQ: -> from, -> group, -> order, -> limit, -> limitPage
PQ: -> join, -> joinUsing
NQ: -> where, -> having, -> union
In practice, non-filtered data can be found, for example, in ajax handlers.
PS Among other things, perhaps someone will take this data to himself in CTF.
UPD: Moment 4: An article more for pentesters who may encounter an application on Zend.