Heim > Artikel > Backend-Entwicklung > Eine Erklärung, wie man SQL-Injection in PHP verhindert
Das Verhindern von SQL-Injection ist das beste Programm zum Schreiben auf unserer täglichen PHP-Entwicklungswebsite, da es meiner Meinung nach viele junge PHP-Programmierer nicht zum Verhindern von SQL-Injection geschrieben hat Deshalb werden wir heute darüber sprechen, wie man PHP verwendet, um SQL-Injection zu verhindern.
Ursache
Einerseits habe ich kein Bewusstsein dafür, dass einige Daten nicht streng überprüft und dann direkt zusammengefügt wurden in SQL zur Abfrage. Dies führt zu Schwachstellen wie:
$id = $_GET['id']; $sql = "SELECT name FROM users WHERE id = $id";
Da es keine Datentyp-Überprüfung für $_GET['id'] gibt, kann der Injektor jede Art von Daten übermitteln, wie zum Beispiel „ und 1= 1 oder " und andere unsichere Daten. Es ist sicherer, wenn Sie es wie folgt schreiben.
$id = intval($_GET['id']); $sql = "SELECT name FROM users WHERE id = $id";
Konvertieren Sie die ID in den Typ „int“, um unsichere Dinge zu entfernen.
Daten überprüfen
Der erste Schritt zur Verhinderung einer Injektion besteht darin, die Daten zu überprüfen, die gemäß den entsprechenden Vorschriften streng überprüft werden können Typ. Beispielsweise kann der Typ int direkt über intval konvertiert werden:
$id =intval( $_GET['id']);
Zeichen sind komplizierter zu verarbeiten. Formatieren Sie zunächst die Ausgabe über die Sprintf-Funktion, um sicherzustellen, dass es sich um eine Zeichenfolge handelt. Verwenden Sie dann einige Sicherheitsfunktionen, um einige illegale Zeichen zu entfernen, wie zum Beispiel:
$str = addslashes(sprintf("%s",$str)); //也可以用 mysqli_real_escape_string 函数替代addslashes
Dies wird in Zukunft sicherer sein. Natürlich können Sie die Länge der Zeichenfolge weiter bestimmen, um „Pufferüberlaufangriffe“ zu verhindern, wie zum Beispiel:
$str = addslashes(sprintf("%s",$str)); $str = substr($str,0,40); //最大长度为40
Parameterisierte Bindung
Die parametrisierte Bindung ist ein weiteres Hindernis zur Verhinderung der SQL-Injection. Sowohl PHP MySQLi als auch PDO bieten diese Funktionalität. Beispielsweise kann MySQLi wie folgt abfragen:
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world'); $stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); $code = 'DEU'; $language = 'Bavarian'; $official = "F"; $percent = 11.2; $stmt->bind_param('sssd', $code, $language, $official, $percent);
PDO ist noch praktischer, wie zum Beispiel:
/* Execute a prepared statement by passing an array of values */ $sql = 'SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'; $sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); $sth->execute(array(':calories' => 150, ':colour' => 'red')); $red = $sth->fetchAll(); $sth->execute(array(':calories' => 175, ':colour' => 'yellow')); $yellow = $sth->fetchAll();
Die meisten von uns verwenden das PHP-Framework zum Programmieren, daher ist es am besten SQL selbst nicht buchstabieren. Abfrage gemäß der vom Framework vorgegebenen Parameterbindung . Wenn Sie auf komplexere SQL-Anweisungen stoßen, müssen Sie bei der eigenen Schreibweise auf ein strenges Urteilsvermögen achten. Sie können auch selbst eine vorbereitete Anweisung schreiben, ohne PDO oder MySQLi zu verwenden, z. B. die Abfrageanweisung „wordprss“. Es ist ersichtlich, dass sie ebenfalls einer strengen Typüberprüfung unterzogen wurde.
function prepare( $query, $args ) { if ( is_null( $query ) ) return; // This is not meant to be foolproof -- but it will catch obviously incorrect usage. if ( strpos( $query, '%' ) === false ) { _doing_it_wrong( 'wpdb::prepare' , sprintf ( ( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' ); } $args = func_get_args(); array_shift( $args ); // If args were passed as an array (as in vsprintf), move them up if ( isset( $args[ 0] ) && is_array( $args[0]) ) $args = $args [0]; $query = str_replace( "'%s'", '%s' , $query ); // in case someone mistakenly already singlequoted it $query = str_replace( '"%s"', '%s' , $query ); // doublequote unquoting $query = preg_replace( '|(?<!%)%f|' , '%F' , $query ); // Force floats to be locale unaware $query = preg_replace( '|(?<!%)%s|', "'%s'" , $query ); // quote the strings, avoiding escaped strings like %%s array_walk( $args, array( $this, 'escape_by_ref' ) ); return @ vsprintf( $query, $args ); }
Zusammenfassung
Sicherheit ist auch sehr wichtig, die Grundkompetenzen einer Person sind das Projekt voller Schlupflöcher, und die Skalierbarkeit spielt keine Rolle, wie gut die Wartbarkeit ist. Schenken Sie in normalen Zeiten mehr Aufmerksamkeit, etablieren Sie ein Sicherheitsbewusstsein und entwickeln Sie eine Gewohnheit. Natürlich wird eine gewisse grundlegende Sicherheit nicht die Zeit des Codierens in Anspruch nehmen. Wenn Sie diese Gewohnheit entwickeln, können Sie es auch dann mit hoher Qualität erledigen, wenn das Projekt dringend ist und die Zeit knapp ist. Warten Sie nicht, bis alle Dinge, für die Sie in Zukunft verantwortlich sind, einschließlich der Datenbank, weggenommen sind und Verluste verursacht wurden, bevor Sie es ernst nehmen. gegenseitige Ermutigung!
Verwandte Artikel:
Ausführliche Erklärung, wie man SQL-Injection in PHP verhindert
Einführung in die Funktion von PHP, um SQL-Injection zu verhindern
Das obige ist der detaillierte Inhalt vonEine Erklärung, wie man SQL-Injection in PHP verhindert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!