Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Vermeidung von MySQL-Injektionen mit der Klasse Zend_Db

Ich habe einen Großteil des Codes für Datenbankparameter und Quoting in Zend Framework geschrieben, als ich der Teamleiter für das Projekt war (bis Version 1.0).

Ich habe versucht, nach Möglichkeit Best Practices zu fördern, aber ich musste ein Gleichgewicht mit Benutzerfreundlichkeit finden.

Beachten Sie, dass Sie immer den String-Wert eines Zend_Db_Select untersuchen können Objekt, um zu sehen, wie es sich entschieden hat, zu zitieren.

print $select; // invokes __toString() method

Sie können auch den Zend_Db_Profiler verwenden um die SQL zu inspizieren, die in Ihrem Namen von Zend_Db ausgeführt wird .

$db->getProfiler()->setEnabled(true);
$db->update( ... );
print $db->getProfiler()->getLastQueryProfile()->getQuery(); 
print_r $db->getProfiler()->getLastQueryProfile()->getQueryParams(); 
$db->getProfiler()->setEnabled(false);

Hier sind einige Antworten auf Ihre spezifischen Fragen:

  • Zend_Db_Select::where('last_name=?', $lname)

    Werte sind entsprechend angegeben. Obwohl die Datei „? " sieht aus wie ein Parameter-Platzhalter, in dieser Methode wird das Argument tatsächlich angemessen zitiert und interpoliert. Es ist also kein echter Abfrageparameter. Tatsächlich erzeugen die folgenden beiden Anweisungen genau dieselbe Abfrage wie die obige Verwendung:

    $select->where( $db->quoteInto('last_name=?', $lname) );
    $select->where( 'last_name=' . $db->quote($lname) );
    

    Wenn Sie jedoch einen Parameter übergeben, der ein Objekt vom Typ Zend_Db_Expr ist , dann ist es nicht zitiert. Sie sind für die Risiken der SQL-Einschleusung verantwortlich, da sie wörtlich interpoliert wird, um Ausdruckswerte zu unterstützen:

    $select->where('last_modified < ?', new Zend_Db_Expr('NOW()'))
    

    Jeder andere Teil dieses Ausdrucks, der zitiert oder abgegrenzt werden muss, liegt in Ihrer Verantwortung. Wenn Sie beispielsweise PHP-Variablen in den Ausdruck interpolieren, liegt die Sicherheit in Ihrer Verantwortung. Wenn Sie Spaltennamen haben, die SQL-Schlüsselwörter sind, müssen Sie diese selbst mit quoteIdentifier() trennen . Beispiel:

    $select->where($db->quoteIdentifier('order').'=?', $myVariable)
    
  • Zend_Db_Adapter_Abstract::insert( array('colname' => 'value') )

    Tabellen- und Spaltennamen sind getrennt, es sei denn, Sie deaktivieren AUTO_QUOTE_IDENTIFIERS .

    Werte werden als echte Abfrageparameter parametrisiert (nicht interpoliert). Es sei denn, der Wert ist ein Zend_Db_Expr -Objekt, in diesem Fall wird es wörtlich interpoliert, sodass Sie Ausdrücke oder NULL einfügen können oder was auch immer.

  • Zend_Db_Adapter_Abstract::update( array('colname' => 'value'), $where )

    Tabellen- und Spaltennamen sind getrennt, es sei denn, Sie deaktivieren AUTO_QUOTE_IDENTIFIERS .

    Werte werden parametrisiert, es sei denn sie sind Zend_Db_Expr Objekte, wie in insert() Methode.

    Das $where -Argument wird überhaupt nicht gefiltert, daher sind Sie für alle SQL-Injection-Risiken in diesem verantwortlich. Sie können das quoteInto() verwenden Methode, um das Zitieren bequemer zu machen.