php


Doctrine queryBuilder: SQL Injection risk in addOrderBy() method?


I a using Doctrine in a Symfony 2.8 project and I wonder if there is any risk of SQL Injections when using the addOrderBy() method of the queryBuilder:
// Order options. Real code does not specify this manually, but receives
// the options via user form input
$orderBy' = array(
'column1' => 'ASC',
'column2' => 'DESC',
...
'columnN' => 'ASC',
);
$qb = $this->em->createQueryBuilder();
...
foreach ($orderBy as $column => $orderOption) {
$qb->addOrderBy("e.$column", $orderOption);
// Does not work:
// $qb->addOrderBy("e.$column", ':orderOption')
// ->setParameter('orderOption', $orderOption);
//
// Error: Expected end of string, got ':orderOption'"
}
// Result is something like:
...ORDER BY e0_.column1 ASC, e0_.column2 DESC...
The problem is, that the order options are received via user form input that could be manipulated to something like ; DROP TABLE someTable instead of ASC or DESC.
I already tried this, but the query builder doesn't seem to accept multiple queries separated by ;, which does not mean, that there could not be any other/better injections :-)
Of course the problem could easily be solved by filtering the received results and skip all invalid search options. But I am trying to understand, if the addOrderBy() method in general. Is it save to pass any value to the method and Doctrine will handle the rest, or is there a potential risk?
I wonder why the ->setParameter() method does not work, as it would when using ->where().
Short answer is that column names submitted by form could in fact be used for a sql injection attack. Doctrine assumes you have properly validated column (and table) names.
The doctrine code is fairly easy to read and it's worth taking a look at for these sorts of questions:
public function addOrderBy($sort, $order = null)
{
$orderBy = ($sort instanceof Expr\OrderBy) ? $sort : new Expr\OrderBy($sort, $order);
return $this->add('orderBy', $orderBy, true);
}
Note that there is no value at all in using Expr in your queries. Doctrine takes care of generating them for you.
$this->add is a bit more complicated but basically the second argument ends up being passed along with no escaping or filtering etc.
I wonder why the ->setParameter() method does not work, as it would
when using ->where()
The important concept is that prepared statements only protect values not column or table names.
So again, it entirely up to you to filter table/column names coming from the wild. And looking at the source can be informative.
You can use the Expr class: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html#the-expr-class
Or a simple function/method to return a valid value:
function orderOption($option, $defaultOption = 'ASC') {
if (in_array(strtoupper($option), ['ASC', 'DESC']) {
return $option;
}
return $defaultOption;
}

Related Links

What's the correct way to reuse connections in case of PHP and MySQL?
Print the value in loop in Jquery ready function
PHP stdClass question
[PHP]: Error -> Too few arguments in sprintf();
how to implement conditional htmlspecialchars?
Javascript & jQuery escaping quotes
Possible to add javascript to Zend_Form_Element_Radio?
How to write a foreach that will produce the results I want
Where is extension being set?
Call a method from an included file NOT from file that inclued it php
Looping a multidimensional array in php
PHP: how to open a zip
POSTing to different action with Zend_Form (and validation)
PHP GD - Crop Shape
$_POST as $key => $value using checkboxes
Wrong result when using mycrypt_cfb

Categories

HOME
hpoo
orientdb
events
mc
dotnetnuke
jms
kendo-dropdown
concurrency
postgresql-9.4
enums
devexpress
hid
stacktrace.js
risk-management
odata
jersey-2.0
google-webmaster-tools
material-components
specifications
bellman-ford
lapack
parsley.js
jodatime
bnf
l20n
asciimath
google-sites
scheduled-tasks
infrared
libgit2
jitsi
yii2-basic-app
tableview
altium-designer
web-push
crud
msdeploy
basex
ccavenue
bobo-browse.net
amazon-cloudtrail
ninject
dnsmasq
unmarshalling
snap-framework
series
wampsharp
overwrite
image-optimization
express-session
keyboard-layout
netstat
icepdf
sendinput
viewmodel
libreoffice-writer
amazon-elastic-beanstalk
spring.net
watir-webdriver
mura
portability
dtd
dynamics-crm-4
finder
oracle-fusion-apps
gapi
libharu
ftp-client
currency-exchange-rates
vim-plugin
ora-04091
mobilefirst-server
ampersand
text-align
mutators
pass-by-value
microsoft-expression-web
configurable-product
image-rotation
xml-signature
qt5.4
accessory
sqlbindparameter
visual-c++-2005
vlab
coalesce
ldif
unicoins
simplecov
multiple-dispatch
cakeyframeanimation
image-scanner
gwt-celltable
play2-mini
canonicalization
tablet-pc
formal-semantics
ninject-interception
explicit
aggregator
oracle-pro-c
inversion
objectinstantiation
regioninfo

Resources

Database Users
RDBMS discuss
Database Dev&Adm
javascript
java
csharp
php
android
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App