Vorwort Dieser Artikel verwendet die Vorverarbeitungsmethode von PDO, um SQL-Injection zu vermeiden. Werfen wir einen Blick auf die ausführliche Einführung. Im PHP-Handbuch unter „PDO – Prepared Statements and Stored Procedures“:
Im Folgenden sind die beiden oben genannten Vorteile aufgeführt: 1. Lassen Sie uns zunächst über die gespeicherten Prozeduren von MySQL sprechen. MySQL5 führte die Funktion für gespeicherte Prozeduren ein. Als die gespeicherte Prozedur erstellt wurde, hatte die Datenbank sie bereits analysiert und optimiert. Zweitens wird nach der Ausführung einer gespeicherten Prozedur eine Kopie dieser gespeicherten Prozedur im Speicher aufbewahrt, sodass diese bei der nächsten Ausführung derselben gespeicherten Prozedur direkt aus dem Speicher gelesen werden kann. Informationen zur Verwendung gespeicherter MySQL-Prozeduren finden Sie unter: https://www.jb51.net/article/7032.htm Für PDO ist das Prinzip dasselbe, außer dass PDO EMULATE_PREPARES (simulierte Vorverarbeitung) unterstützt, die lokal vom PDO-Treiber abgeschlossen wird. Gleichzeitig können Sie die lokale simulierte Vorverarbeitung auch nicht verwenden und sie von MySQL abschließen lassen. Diese beiden Situationen werden weiter unten erläutert. 2. Um SQL-Injection zu verhindern, habe ich tcpdump und wireshark verwendet, um das Paket zur Analyse zu erfassen. Führen Sie einen Codeabschnitt auf der virtuellen Maschine aus, um eine Anfrage an das Remote-MySQL zu initiieren: <?php $pdo = neues PDO("mysql:host=10.121.95.81;dbname=thor_cms;charset=utf8", "root", "qihoo@360@qihoo"); $st = $pdo->prepare("Wählen Sie * aus der Freigabe aus, wobei ID =? und UID = ?"); $id = 6; $uid = 521; $st->bindParam(1, $id); $st->bindParam(2, $uid); $st->execute(); $ret = $st->fetchAll(); drucken_r($ret); Generieren Sie Dateien, indem Sie Pakete über tcpdump erfassen: tcpdump -ieth0 -A -s 3000 Port 3306 -w ./mysql.dump sz mysql.dump Öffnen Sie die Datei über Wireshark: Sie können den gesamten Prozess sehen: 3-Wege-Handshake - Anmeldeanforderung - Anforderungsabfrage - Anforderung zum Beenden Wenn Sie sich das Request Query-Paket ansehen, können Sie Folgendes sehen: Hä? Ist das nicht auch eine Verkettung von SQL-Anweisungen? Tatsächlich unterscheidet sich dies nicht von der Art und Weise, wie wir normalerweise mysql_real_escape_string verwenden, um die Zeichenfolge zu escapen und sie dann in SQL-Anweisungen zu verketten. Es ist nur so, dass der lokale PDO-Treiber das Escape abschließt (EMULATE_PREPARES). In diesem Fall ist SQL-Injection immer noch möglich, d. h., wenn mysql_real_escape_string in pdo prepare lokal in PHP aufgerufen wird, um die Abfrage auszuführen, der lokale Einzelbyte-Zeichensatz verwendet wird und wenn wir mehrbytecodierte Variablen übergeben, können immer noch SQL-Injection-Schwachstellen auftreten (eines der Probleme in Versionen vor PHP 5.3.6, weshalb empfohlen wird, auf PHP 5.3.6+ zu aktualisieren und den Zeichensatz in der DSN-Zeichenfolge anzugeben, wenn PDO verwendet wird). Bei Versionen vor PHP 5.3.6 kann der folgende Code immer noch SQL-Injection-Probleme verursachen: $pdo->query('Namen festlegen GBK'); $var = chr(0xbf) . chr(0x27) . " ODER 1=1 /*"; $query = "AUSWÄHLEN * FROM info WHERE name = ?"; $stmt = $pdo->prepare($query); : $stmt->execute(array($var)); Das richtige Escape-Verfahren sollte darin bestehen, den Zeichensatz für den MySQL-Server anzugeben und die Variable an den MySQL-Server zu senden, um das Zeichen-Escape-Verfahren abzuschließen. Wie können wir also das lokale PHP-Escapen deaktivieren und das Escapen dem MySQL-Server überlassen? PDO hat einen Parameter namens PDO::ATTR_EMULATE_PREPARES, der angibt, ob die lokale simulierte Vorbereitung von PHP verwendet werden soll. Dieser Parameter ist standardmäßig auf „true“ eingestellt. Ändern wir ihn in „false“ und erfassen dann das Paket. Fügen Sie nach der ersten Codezeile hinzu $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); Verwenden Sie tcpdump, um das Paket erneut zu erfassen. Über Wireshark können wir Folgendes sehen: PHP verwendet die Methode prepare--execute zum Senden von SQL-Anweisungen Dieses Mal wird die Variablen-Escape-Verarbeitung vom MySQL-Server durchgeführt. Da die Variablen und die SQL-Vorlage zweimal gesendet werden, gibt es kein SQL-Injection-Problem, aber es wird offensichtlich eine weitere Übertragung geben, die nach php5.3.6 nicht mehr erforderlich ist. Hinweise zur Verwendung von PDO 1. Aktualisieren Sie PHP auf 5.3.6+. Für Produktionsumgebungen wird dringend empfohlen, auf PHP 5.3.9+ oder PHP 5.4+ zu aktualisieren. PHP 5.3.8 weist eine schwerwiegende Hash-Kollisions-Sicherheitslücke auf. 2. Wenn Sie PHP 5.3.6+ verwenden, geben Sie bitte das Zeichensatzattribut im PDO DSN an. Weniger als 5.3.6: $dbh = neues PDO($dsn,$user,$pass,array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8")); 3. Wenn Sie PHP 5.3.6 oder früher verwenden, setzen Sie den Parameter PDO::ATTR_EMULATE_PREPARES auf „false“ (das heißt, lassen Sie den MySQL-Server die Variablen handhaben). PHP 5.3.6 und spätere Versionen haben dieses Problem bereits behandelt, unabhängig davon, ob Sie lokal simuliertes Prepare verwenden oder Prepare des MySQL-Servers aufrufen. 4. Wenn Sie PHP 5.3.6 oder früher verwenden, geben Sie den Wert von emulatePrepare in der Datenbankkonfigurationsdatei bitte als „false“ an, da das Yii-Framework den Wert von ATTR_EMULATE_PREPARES nicht standardmäßig festlegt. Notiz: 1. Warum muss ich Setnamen <charset> ausführen, wenn ich den Zeichensatz im DSN angebe? Tatsächlich hat der Satz von Namen <charset> zwei Funktionen: Teilen Sie dem MySQL-Server mit, welche Kodierung der Client (PHP-Programm) ihm übermittelt hat. Teilen Sie dem MySQL-Server mit, welche Kodierung der Client für das Ergebnis benötigt Das heißt, wenn die Datentabelle den GBK-Zeichensatz verwendet und das PHP-Programm die UTF-8-Kodierung nutzt, können wir vor der Ausführung der Abfrage „set names utf8“ ausführen, um dem MySQL-Server mitzuteilen, dass er die richtige Kodierung verwenden soll, ohne die Kodierung im Programm konvertieren zu müssen. Wenn wir auf diese Weise Abfragen in UTF-8-Kodierung an den MySQL-Server senden, liegen die Ergebnisse ebenfalls in UTF-8-Kodierung vor. Dadurch entfällt die Notwendigkeit von Konvertierungsproblemen im Programm. Seien Sie unbesorgt, es entstehen keine verstümmelten Zeichen. Was ist also der Zweck der Angabe des Zeichensatzes in DSN? Es teilt PDO lediglich mit, dass der lokale Treiber beim Escapen den angegebenen Zeichensatz verwenden soll (es legt nicht den Zeichensatz für die MySQL-Serverkommunikation fest). Um den Zeichensatz für die MySQL-Serverkommunikation festzulegen, müssen Sie auch den Befehl set names <charset> verwenden. 2. Der Mord, der durch das Setzen des Attributs PDO::ATTR_EMULATE_PREPARES auf „false“ verursacht wurde: http://my.oschina.net/u/437615/blog/369481 Zusammenfassen Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM. Das könnte Sie auch interessieren:
|
<<: Implementierungsmethode für den Apache AB-Stresstest zur gleichzeitigen Belastung
>>: Docker Swarm von der Bereitstellung bis zum grundlegenden Betrieb
border-radius:10px; /* Alle Ecken sind mit einem ...
Vorwort Wenn CSS die Grundfertigkeit der Front-En...
1. Ordner löschen Beispiel: rm -rf /usr/java Das ...
AWS – Amazons Cloud-Computing-Serviceplattform Ic...
【SQL】 Zusammenfassung der SQL-Paging-Abfragen Wäh...
Einführung in das Geo-Modul von Nginx Die Geo-Dir...
Vorwort In MySQL können wir den Befehl EXPLAIN ve...
Wenn der vorhandene Videoplayer die Anforderungen...
Frage Beim Schreiben von Datenbank-SQL ist mir ge...
In diesem Artikelbeispiel wird der spezifische Ja...
Bei der Verwendung von Vue zur Entwicklung von Pr...
1. Laden Sie das Installationspaket von der offiz...
In diesem Artikel zeige ich Ihnen, wie Sie mit Ja...
Inhaltsverzeichnis 1. Was sind Mikroaufgaben? 2. ...
Allerdings ist die Häufigkeit des Shell-Starts se...