SQL Injection Schwachstellen bei der Verwendung von SQL Modellen des Zend Frameworks


15

Beim Verbinden von Tabellen verwende ich SQL-Modelle des Zend Framework. Als Beispiel habe ich meinen aktuellen Code geändert, aber ich denke, Sie werden den Punkt bekommen:

$this->getSelect()->join(
                      array('sections' => $sectionsTableName),
                      'main_table.banner_id = pages.banner_id',
                      array()
                    )
                  ->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
                  ->group('main_table.banner_id'); 

Die Seite wird mit Ajax geladen und der Parameter $ section wird als GET-Parameter ( www.example.com/controllerName/index/display/3?paremeter1=example&section=www.example2.com) gesendet .

Hier ist das Problem, wenn jemand so etwas ausführt:

www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

Auf diese Weise kann der Benutzer die gesamte Datenbank sichern. Die Daten werden nicht angezeigt, SQL führt jedoch einen Speicherauszug durch, der eine SQL-Überladung verursachen kann.

Fragen:

  1. Was ist der beste Weg, um ein solches Szenario zu verhindern?
  2. Jetzt mache ich mir Sorgen um bisherige Kunden. Ist es mit diesem Code möglich, noch mehr Risikomaßnahmen wie Delate oder Alter Table zu treffen? Ich vermute nicht, weil Sie keine andere Anweisung als SELECT in Unterauswahl setzen können, so dass DELETE SQL-Syntaxfehler erzeugen würde. Habe ich recht?

UPDATE: In meinem Beispiel ist die SQL-Injection nicht richtig dargestellt, da in den $ Abschnitten ein Vorzeichen vorhanden ist und daher keine Injection möglich ist. Dies ist jedoch möglich, wenn Sie einen Ganzzahlwert erwarten und keine Ganzzahleingabe filtern. Siehe meinen Kommentar unten.


1
Sie könnten verwenden: $db = Mage::getSingleton('core/resource')->getConnection('core_read');und $db->quote()sogar in Ihrem Fall betrachten $db->quoteInto. Wenn $thiseine Ressource ist, könnten Sie tun: $this->getConnection('core_read')->quoteInto()wenn es sich um eine Sammlung könnten Sie tun: $this->getResource()->getConnection('core_read')->quoteInto(). in diese Richtung. Wenn das hilft, Sie zu Ihrem Ziel zu führen.
Asche

Ich habe gerade festgestellt, dass dieses Szenario nur möglich ist, wenn value eine Ganzzahl ist. Wenn value varchar ist, steht das 'Vorzeichen immer vor dem (Zeichen, und daher ist (SELECTalles andere nur ein String und funktioniert nicht. Wenn das Feld eine Ganzzahl ist, 'wird es nicht benötigt und ermöglicht ein solches Szenario. Ganzzahlen sollten jedoch immer mit gefiltert werden, intval()damit dies auch kein Problem darstellt.
JohnyFree

Was ist, wenn Sie mit dem Schließen des beginnen '? Also ' AND (SELECT ...) '? Übrigens glaube ich nicht, dass Zend dies nicht zitiert ... Und wenn Sie Bindungen verwenden, wird PDO damit umgehen. Verwenden Sie einfach nie Verkettungen wie dieser Stachel:"sections.section= '$section'"
7ochem

@ 7ochem MÜSSEN Sie in diesem Fall Parameter mit binden? und 'wird \'. Aber wenn Sie Integer - Wert verwenden, dann tun Sie es nicht zu binden , da Sie es mit intval reinigen können () PHP - Funktion und ‚etwas wird 0. geworden
JohnyFree

Antworten:


8

Bestätigen Sie Ihre Eingabe!

So gut und so viel du kannst.

Einige Vorschläge für Ihre Validierung:

  1. Überprüfen Sie die Länge der Variablen, die Sie über den GET-Parameter erhalten. Es ist nicht erforderlich, einen endlosen langen String zu akzeptieren.

  2. Bestätigen Sie für einen Domainnamen. Welches Format haben Ihre erwarteten Domainnamen? Ist es immer www.mydomain.tld? Erstellen Sie einen regulären Ausdruck, der nach Übereinstimmungen sucht oder (besser) verwendet Zend_Validate_Hostname:

    $validator = new Zend_Validate_Hostname();
    if ($validator->isValid($hostname)) {
        //hostname is valid - continue
    }
    
  3. Whitelisting: Wissen Sie, mit welchen Domainnamen Sie rechnen müssen? Sie können eine Liste der zulässigen Domänen erstellen und mit diesen vergleichen. Lass den Rest fallen.

    $allowedDomains = array('www.domain1.tld','www.domain2.tld');
  4. Domainnamen und / oder Zeichen auf die schwarze Liste setzen: Wenn Sie einen Domainnamen erwarten, müssen Sie keine anderen Zeichen als az und 0-9 und "." (es sei denn, Sie arbeiten mit speziellen Domainnamen).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.