Heim > Backend-Entwicklung > PHP-Tutorial > So verhindern Sie die SQL-Injection in PHP

So verhindern Sie die SQL-Injection in PHP

伊谢尔伦
Freigeben: 2016-11-24 14:35:57
Original
1357 Leute haben es durchsucht

Problembeschreibung:
Wenn die vom Benutzer eingegebenen Daten ohne Verarbeitung in eine SQL-Abfrageanweisung eingefügt werden, ist die Anwendung wahrscheinlich SQL-Injection-Angriffen ausgesetzt, wie im folgenden Beispiel:

$unsafe_variable = $_POST['user_input'];
Nach dem Login kopieren

mysql_query("INSERT INTO `table` (`column`) VALUES ('" . $unsafe_variable . "')");
Weil die Eingabe des Benutzers so aussehen könnte:

value'); DROP TABLE table;--
Dann sieht die SQL-Abfrage wie folgt aus:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')
Nach dem Login kopieren

Welche wirksamen Methoden sollten angewendet werden, um SQL-Injection zu verhindern?

Beste Antwort (von Theo):
Verwenden Sie vorbereitete Anweisungen und parametrisierte Abfragen. Die vorbereiteten Anweisungen und Parameter werden jeweils zum Parsen an den Datenbankserver gesendet und die Parameter werden als normale Zeichen behandelt. Dieser Ansatz verhindert, dass Angreifer bösartiges SQL einschleusen. Sie haben zwei Möglichkeiten, diese Methode zu implementieren:

1. Verwenden Sie PDO:

$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');  
   
$stmt->execute(array('name' => $name));  
   
foreach ($stmt as $row) {  
    // do something with $row  
}
Nach dem Login kopieren

2. Verwenden Sie mysqli:

$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');  
$stmt->bind_param('s', $name);  
   
$stmt->execute();  
   
$result = $stmt->get_result();  
while ($row = $result->fetch_assoc()) {  
    // do something with $row  
}
Nach dem Login kopieren


Beachten Sie, dass die standardmäßige Verwendung von PDO es der MySQL-Datenbank nicht ermöglicht, echte vorbereitete Anweisungen auszuführen (Gründe siehe unten). Um dieses Problem zu lösen, sollten Sie die PDO-Emulation vorbereiteter Anweisungen deaktivieren. Ein Beispiel für die korrekte Verwendung von PDO zum Erstellen einer Datenbankverbindung ist wie folgt:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');  
   
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);  
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Nach dem Login kopieren

Im obigen Beispiel ist der Fehlerberichtsmodus (ATTR_ERRMODE) nicht erforderlich, es wird jedoch empfohlen, ihn hinzuzufügen . Auf diese Weise stoppt das Skript beim Auftreten eines schwerwiegenden Fehlers (Fatal Error) nicht die Ausführung, sondern gibt dem Programmierer die Möglichkeit, PDOExceptions abzufangen, damit der Fehler ordnungsgemäß behandelt werden kann. Allerdings ist der erste setAttribute()-Aufruf erforderlich, der PDO daran hindert, vorbereitete Anweisungen zu simulieren und echte vorbereitete Anweisungen verwendet, d. h. MySQL führt vorbereitete Anweisungen aus. Dadurch wird sichergestellt, dass Anweisungen und Parameter nicht von PHP verarbeitet wurden, bevor sie an MySQL gesendet wurden, wodurch Angreifer daran gehindert werden, bösartiges SQL einzuschleusen. Um den Grund zu verstehen, lesen Sie bitte diesen Blogbeitrag: Analyse des PDO-Anti-Injektionsprinzips und Vorsichtsmaßnahmen für die Verwendung von PDO. Beachten Sie, dass Sie in älteren PHP-Versionen (<5.3.6) den Zeichensatz nicht über den DSN im PDO-Konstruktor festlegen können, siehe: Der Zeichensatzparameter wurde stillschweigend ignoriert.

Analyse
Was passiert, wenn Sie eine SQL-Anweisung zur Vorverarbeitung und Analyse an den Datenbankserver senden? Teilen Sie der Datenbank-Engine mit, wo Sie filtern möchten, indem Sie einen Platzhalter angeben (ein ? oder einen :name wie im Beispiel oben). Wenn Sie „execute“ aufrufen, wird die vorbereitete Anweisung mit den von Ihnen angegebenen Parameterwerten kombiniert. Der entscheidende Punkt liegt hier: Der Parameterwert wird mit der analysierten SQL-Anweisung kombiniert, nicht mit der SQL-Zeichenfolge. Die SQL-Injection wird durch Skripte ausgelöst, die beim Erstellen von SQL-Anweisungen schädliche Zeichenfolgen enthalten. Durch die Trennung von SQL-Anweisungen und Parametern verhindern Sie also das Risiko einer SQL-Injection. Alle von Ihnen gesendeten Parameterwerte werden als normale Zeichenfolgen behandelt und vom Datenbankserver nicht analysiert. Um auf das obige Beispiel zurückzukommen: Wenn der Wert der Variablen „$name“ „Sarah“ ist; Ein weiterer Vorteil der Verwendung vorbereiteter Anweisungen besteht darin, dass, wenn Sie dieselbe Anweisung mehrmals in derselben Datenbankverbindungssitzung ausführen, sie nur einmal analysiert wird, was die Ausführungsgeschwindigkeit etwas verbessern kann. Wenn Sie fragen möchten, wie das Einfügen erfolgt, schauen Sie sich bitte das folgende Beispiel an (mit PDO):

$preparedStatement = $db->prepare(&#39;INSERT INTO table (column) VALUES (:column)&#39;);  
   
$preparedStatement->execute(array(&#39;column&#39; => $unsafeValue));
Nach dem Login kopieren


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage