2016-12-07 3 views
3

mich mit Doctrine in einem Symfony 2.8 Projekt und ich frage mich, ob es ein Risiko von SQL Injections, wenn die addOrderBy() Methode der queryBuilder mit:Doctrine queryBuilder: SQL-Injection-Risiko in addOrderBy() -Methode?

// 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... 

Das Problem ist, dass die Auftragsoptionen empfangen werden über die Benutzer Formulareingabe, die zu etwas wie ; DROP TABLE someTable anstelle von ASC oder DESC manipuliert werden könnte.

Ich habe bereits versucht, diese, aber der Query Builder scheint nicht von ;, getrennt mehrere Abfragen zu akzeptieren, was nicht bedeutet, dass es keine andere/besseren Injektionen :-)

Natürlich könnte die Problem könnte leicht gelöst werden, indem die empfangenen Ergebnisse gefiltert und alle ungültigen Suchoptionen übersprungen werden. Aber ich versuche zu verstehen, ob die addOrderBy() Methode im Allgemeinen. Ist es sicher, irgendeinen Wert an die Methode zu übergeben, und Doctrine erledigt den Rest, oder besteht ein potenzielles Risiko?

Ich frage mich, warum die Methode nicht funktioniert, wie es bei der Verwendung ->where() wäre.

Antwort

7

Kurze Antwort ist, dass Spaltennamen von Formular abgeschickt könnte in der Tat verwendet werden, für ein SQL-Injektion Angriff. Doctrine geht davon aus, dass Sie Spalten- (und Tabellen-) Namen ordnungsgemäß validiert haben.

Die Lehre Code ist ziemlich einfach zu lesen und es lohnt sich einen Blick auf für diese Art von Fragen unter:

public function addOrderBy($sort, $order = null) 
{ 
    $orderBy = ($sort instanceof Expr\OrderBy) ? $sort : new Expr\OrderBy($sort, $order); 

    return $this->add('orderBy', $orderBy, true); 
} 

Beachten Sie, dass es keinen Wert überhaupt bei der Verwendung Expr in Ihrer Anfragen. Doctrine kümmert sich darum, sie für Sie zu generieren.

$ this-> add ist ein wenig komplizierter, aber im Grunde das zweite Argument landet zusammen mit kein Entkommen weitergegeben werden oder Filtern usw.

Ich frage mich, warum die -> setParameter() Methode funktioniert nicht wie es wäre, bei der Verwendung von -> wo()

Das wichtige Konzept ist, dass vorbereitete Anweisungen nur Werte schützen nicht Spalte oder Tabellennamen.

Also noch einmal, es liegt ganz bei Ihnen, Tabelle/Spaltennamen aus der Wildnis zu filtern. Und der Blick auf die Quelle kann informativ sein.

1

können Sie verwenden, um die Expr Klasse: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html#the-expr-class

Oder eine einfache Funktion/Methode einen gültigen Wert zurück:

function orderOption($option, $defaultOption = 'ASC') { 
    if (in_array(strtoupper($option), ['ASC', 'DESC']) { 
     return $option; 
    } 
    return $defaultOption; 
} 
+0

Vielen Dank, aber wie in der Frage erklärt, es ist nicht so viel über das Finden einer sicheren Filterfunktion, sondern darüber, ob 'addOrderBy()' ein Risiko an erster Stelle ist. –

+0

Verwenden Sie 'Expr'. – rogeriolino

+0

Ich möchte 'Expr' nicht verwenden :) Ich möchte verstehen, ob ein Risiko bei der Verwendung von' addOrderBy() 'besteht. –

Verwandte Themen