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

How to add a custom year drop-down in place of Export CSV drop-down on admin panel for custom grid and filter the collection?
Sending boolean values with $.ajax to PHP
Loop row in bootstrap every 3 columns
Get friends name/id list form graph api into array
LAMP shows index.php in var/www/html instead of project
How To play 25MB+ audio file directly from google drive in HTML 5?
PHP/MYSQL - Select option value not being sent?
Laravel : How to use a parameters in a Form POST to be use in a Route::post?
How to convert object format to json format in php
laravel,how i can change the code to return an array?
How to make At Least Two Field Required to fill in Laravel 5.2
How do I allow PHP to run when the script is not in the URL?
How to check if a file is BEING used, i.e. some command is being executed on the data in that file?
Display profile data from database when login
How to integrate laravel packages into an application
Log into a Django project using Magento user database SSO

Categories

HOME
amazon-web-services
oracle
macos-sierra
generics
shinyapps
kendo-dropdown
workflow
swi-prolog
foaf
website
greasemonkey
tibco
supercollider
graphql-js
smooks
temperature
animated-gif
android-cardview
msdeploy
sap-lumira
bobo-browse.net
ibm-connections
javax.persistence
steam-web-api
john-the-ripper
payeezy
markov-chains
ftp-server
nanogallery
eclipse-gmf
android-alarms
unification
sspi
iscroll
slideshow
vesta
react-intl
adblock
return-type
deployd
xcglogger
sony-future-lab-n
photoswipe
sonicmq
google-news
openerp-6
maatwebsite-excel
ipywidgets
xcode6.4
nclam
dmarc
dpkg
strpos
urbit
vaadin4spring
mnesia
grinder
linuxbrew
lowercase
screen-orientation
algebraixlib
componentart
nsmutabledata
operands
rubber
device-admin
nesper
inputbox
reference-counting
xmi
jchartfx
mod-perl
xsd2code
days
android-authenticator
django-filebrowser
idispatch
popup-blocker
telerik-ajax
autosize
netstream
affinetransform
dynamic-c
asio
will-paginate
database-deadlocks
canonicalization
kernel32
kohana-auth
tablet-pc
hungarian-notation
tacit-programming
downcasting
rakudo
comment-conventions
remote-working
error-detection

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App