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§ion=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:
- Was ist der beste Weg, um ein solches Szenario zu verhindern?
- 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.
quelle
$db = Mage::getSingleton('core/resource')->getConnection('core_read');
und$db->quote()
sogar in Ihrem Fall betrachten$db->quoteInto
. Wenn$this
eine 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.'
Vorzeichen immer vor dem(
Zeichen, und daher ist(SELECT
alles 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.'
? 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'"
Antworten:
Bestätigen Sie Ihre Eingabe!
So gut und so viel du kannst.
Einige Vorschläge für Ihre Validierung:
Ü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.
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
: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.
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).
quelle