Heim  >  Artikel  >  Backend-Entwicklung  >  Eine Erklärung, wie man SQL-Injection in PHP verhindert

Eine Erklärung, wie man SQL-Injection in PHP verhindert

韦小宝
韦小宝Original
2018-03-01 09:58:452173Durchsuche

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&#39;; $sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(&#39;:calories&#39; => 150, &#39;:colour&#39; => &#39;red&#39;));
$red = $sth->fetchAll();
$sth->execute(array(&#39;:calories&#39; => 175, &#39;:colour&#39; => &#39;yellow&#39;));
$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, &#39;%&#39; ) === false ) {
         _doing_it_wrong( &#39;wpdb::prepare&#39; , 
         sprintf ( ( &#39;The query argument of %s
                 must have a placeholder.&#39; ), &#39;wpdb::prepare()&#39; ), &#39;3.9&#39; );
   }
    $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( "&#39;%s&#39;", &#39;%s&#39; , $query ); 
        // in case someone mistakenly already singlequoted it
    $query = str_replace( &#39;"%s"&#39;, &#39;%s&#39; , $query ); 
        // doublequote unquoting
    $query = preg_replace( &#39;|(?<!%)%f|&#39; , &#39;%F&#39; , $query ); 
        // Force floats to be locale unaware
    $query = preg_replace( &#39;|(?<!%)%s|&#39;, "&#39;%s&#39;" , $query ); 
        // quote the strings, avoiding escaped strings like %%s
    array_walk( $args, array( $this, &#39;escape_by_ref&#39; ) );
    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!

Stellungnahme:
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