Dieser Artikel vermittelt Ihnen relevantes Wissen über PHP. Er befasst sich hauptsächlich mit der Frage, was eine Vorverarbeitungsanweisung ist. Wie verhindert die vorverarbeitete PHP-Abfrage die SQL-Injection? Freunde, die interessiert sind, können einen Blick darauf werfen. Ich hoffe, es wird für alle hilfreich sein.
Wie verhindert die vorverarbeitete PHP-Abfrage die SQL-Injection?
Derzeit ist die effektivste Möglichkeit, SQL-Injection zu verhindern, die Verwendung vorbereiteter Anweisungen und parametrisierter Abfragen.
Nehmen Sie als Beispiel die am häufigsten verwendete PHP-PDO-Erweiterung.
Einführung in vorbereitete Aussagen in der offiziellen Dokumentation
Was sind vorbereitete Aussagen?
Betrachten Sie es als eine kompilierte Vorlage der SQL, die Sie ausführen möchten, die mithilfe variabler Parameter angepasst werden kann.
Zwei Hauptvorteile vorbereiteter Anweisungen:
1; Die Abfrage muss nur einmal analysiert (oder vorverarbeitet) werden, kann aber mehrmals mit denselben oder unterschiedlichen Parametern ausgeführt werden. Wenn eine Abfrage bereit ist, analysiert, kompiliert und optimiert die Datenbank den Plan zur Ausführung der Abfrage. Dieser Vorgang dauert bei komplexen Abfragen länger und kann Ihre Anwendung erheblich verlangsamen, wenn dieselbe Abfrage mehrmals mit unterschiedlichen Parametern wiederholt werden muss. Durch die Verwendung vorbereiteter Anweisungen können Sie wiederholte Analyse-/Kompilierungs-/Optimierungszyklen vermeiden. Einfach ausgedrückt verbrauchen vorbereitete Anweisungen weniger Ressourcen und werden daher schneller ausgeführt.
2. Die in der vorbereiteten Anweisung bereitgestellten Parameter müssen nicht in Anführungszeichen gesetzt werden, der Treiber verarbeitet sie automatisch. Wenn Ihre Anwendung nur vorbereitete Anweisungen verwendet, können Sie sicherstellen, dass keine SQL-Injection erfolgt. (Wenn jedoch andere Teile der Abfrage aus nicht maskierten Eingaben erstellt werden, besteht immer noch das Risiko einer SQL-Injection.)
Das Merkmal von PDO besteht darin, dass PDO die Verarbeitung simuliert, wenn der Treiber die Vorverarbeitung nicht unterstützt. Zu diesem Zeitpunkt ist der vorverarbeitungsparametrisierte Abfrageprozess im PDO-Simulator abgeschlossen. Der PDO-Simulator maskiert die Eingabeparameter lokal gemäß dem im DSN angegebenen Zeichensatz, fügt sie dann zu einer vollständigen SQL-Anweisung zusammen und sendet sie an den MySQL-Server.
Ob der PDO-Simulator Eingabeparameter korrekt umgehen kann, ist also der Schlüssel zum Abfangen der SQL-Injection.
Bei PHP-Versionen vor 5.3.6 ignoriert DSN (Datenquellenname) standardmäßig den Zeichensatzparameter. Wenn Sie zu diesem Zeitpunkt den lokalen Escape von PDO verwenden, kann dies immer noch zu einer SQL-Injection führen.
Daher setzt die unterste Ebene des Laravel-Frameworks direkt PDO::ATTR_EMULATE_PREPARES=false, um sicherzustellen, dass SQL-Anweisungen und Parameterwerte nicht von PHP analysiert werden, bevor sie an den MySQL-Server gesendet werden.
Die Implementierung von PHP
// 查询 $calories = 150; $colour = 'red'; $sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'); $sth->bindValue(':calories', $calories, PDO::PARAM_INT); $sth->bindValue(':colour', $colour, PDO::PARAM_STR); $sth->execute();
// 插入,修改,删除 $preparedStmt = $db->prepare('INSERT INTO table (column) VALUES (:column)'); $preparedStmt->execute(array(':column' => $unsafeValue));
Die zugrunde liegende Implementierung von Laravel
// 查询的实现 public function select($query, $bindings = [], $useReadPdo = true) { return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { if ($this->pretending()) { return []; } $statement = $this->prepared( $this->getPdoForSelect($useReadPdo)->prepare($query) ); $this->bindValues($statement, $this->prepareBindings($bindings)); $statement->execute(); return $statement->fetchAll(); }); } // 修改删除的实现 public function affectingStatement($query, $bindings = []) { return $this->run($query, $bindings, function ($query, $bindings) { if ($this->pretending()) { return 0; } $statement = $this->getPdo()->prepare($query); $this->bindValues($statement, $this->prepareBindings($bindings)); $statement->execute(); $this->recordsHaveBeenModified( ($count = $statement->rowCount()) > 0 ); return $count; }); }
Empfohlenes Lernen: „PHP-Video-Tutorial“
Das obige ist der detaillierte Inhalt vonEin Artikel, der analysiert, wie die vorverarbeiteten Abfragen von PHP die SQL-Injection verhindern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!