Heim  >  Artikel  >  Backend-Entwicklung  >  Um SQL-Injection in PHP zu verhindern, verwenden Sie keine Addslashes und mysql_real_escape_string mehr.

Um SQL-Injection in PHP zu verhindern, verwenden Sie keine Addslashes und mysql_real_escape_string mehr.

WBOY
WBOYOriginal
2016-08-08 09:30:021077Durchsuche

Der Blogger ist an verschiedenen Internet-Technologien interessiert. Er ist oft wortreich und wird oft von Zwangsstörungen begleitet. Wenn Sie denken, dass der Artikel für Sie hilfreich ist, können Sie mir folgen. Bitte markieren Sie beim Nachdruck „Dark Blue Scythe“


Ich habe viele PHP-Websites gesehen, die immer noch Addslashes und str_replace verwenden, um SQL-Injection zu verhindern, schauen Sie sich das an Baidu verwendet sie auch. In der Praxis hat sich herausgestellt, dass sogar mysql_real_escape_string Möglichkeiten bietet, diese zu umgehen. Drei Methoden , dann wird mein Blogbeitrag sinnvoll sein, um alle Nachzügler daran zu erinnern, diese Grube zu umgehen.

Aus Rücksicht darauf, Bäume für zukünftige Generationen zu pflanzen, anstatt Löcher zu graben, stellen wir PHP- und MYSQL-Versionen zur Verfügung Informationen, damit das „Problem“ in Zukunft kein „Problem“ mehr ist.

Verwenden Sie str_replace und verschiedene Funktionen zum Ersetzen von PHP-Zeichen, um diese Art von „Schwarzem“ zu verhindern Die „Listen“-Verteidigung hat sich als nicht haltbar erwiesen.

Das Folgende ist eine Methode zum Umgehen von addslasher und mysql_real_escape_string ( Trick).


Hinweis: Obwohl der Trick unter MYSQL5.5.37-log behoben wurde, handelt es sich immer noch um die Injektion Da das Problem noch nicht vollständig gelöst ist, schlage ich vor, sofort Verbesserungen vorzunehmen. Deshalb spreche ich auch über mehrere Methoden, mit denen Programmierer ihre Fähigkeiten schnell verbessern können. Ein sehr wichtiger Punkt, der in „.

Hinweis: Wenn Sie nicht sicher sind, ob bei Ihrem System das Risiko einer SQL-Injection besteht, stellen Sie bitte die folgende DEMO auf Ihrem Server bereit. Wenn die laufenden Ergebnisse gleich sind, lesen Sie bitte die endgültige perfekte Lösung.

MYSQL:

mysql> select version();
+---------------------+
| version()           |
+---------------------+
| 5.0.45-community-ny |
+---------------------+
1 row in set (0.00 sec)
mysql> create database test default charset GBK;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
Database changed
mysql> CREATE TABLE users (
    username VARCHAR(32) CHARACTER SET GBK,
    password VARCHAR(32) CHARACTER SET GBK,
    PRIMARY KEY (username)
);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into users SET username='ewrfg', password='wer44';
Query OK, 1 row affected (0.01 sec)
mysql> insert into users SET username='ewrfg2', password='wer443';
Query OK, 1 row affected (0.01 sec)
mysql> insert into users SET username='ewrfg4', password='wer4434';
Query OK, 1 row affected (0.01 sec)=

PHP:

<?php
echo "PHP version: ".PHP_VERSION."\n";

mysql_connect(&#39;servername&#39;,&#39;username&#39;,&#39;password&#39;);
mysql_select_db("test");
mysql_query("SET NAMES GBK");

$_POST[&#39;username&#39;] = chr(0xbf).chr(0x27).&#39; OR username = username /*&#39;;
$_POST[&#39;password&#39;] = &#39;guess&#39;;

$username = addslashes($_POST[&#39;username&#39;]);
$password = addslashes($_POST[&#39;password&#39;]);
$sql = "SELECT * FROM  users WHERE  username = &#39;$username&#39; AND password = &#39;$password&#39;";
$result = mysql_query($sql) or trigger_error(mysql_error().$sql);

var_dump(mysql_num_rows($result));
var_dump(mysql_client_encoding());

$username = mysql_real_escape_string($_POST[&#39;username&#39;]);
$password = mysql_real_escape_string($_POST[&#39;password&#39;]);
$sql = "SELECT * FROM  users WHERE  username = &#39;$username&#39; AND password = &#39;$password&#39;";
$result = mysql_query($sql) or trigger_error(mysql_error().$sql);

var_dump(mysql_num_rows($result));
var_dump(mysql_client_encoding());

mysql_set_charset("GBK");
$username = mysql_real_escape_string($_POST[&#39;username&#39;]);
$password = mysql_real_escape_string($_POST[&#39;password&#39;]);
$sql = "SELECT * FROM  users WHERE  username = &#39;$username&#39; AND password = &#39;$password&#39;";
$result = mysql_query($sql) or trigger_error(mysql_error().$sql);

var_dump(mysql_num_rows($result));
var_dump(mysql_client_encoding());

Das Ergebnis:
PHP version: 5.2.5
int(3)
string(6) "latin1"
int(3)
string(6) "latin1"
int(0)
string(3) "gbk" 
Das können Sie siehe es Ob Addslashes oder mysql_real_escape_string verwenden, Ich kann Programmierschwachstellen nutzen, um einen Injektionsangriff zu erreichen, der es mir ermöglicht, mich durch Eingabe eines beliebigen Passworts beim Server anzumelden! ! ! ! (Ich werde nicht näher auf das Prinzip des Angriffs eingehen. Interessierte Schüler können sich mit den Single-Byte- und Multi-Byte-Problemen bei der Zeichenkodierung befassen.)

Hinweis: Der dritte mysql_real_escape_string kann die Injektion verhindern, weil mysql_escape_string selbst die aktuelle Codierung nicht bestimmen kann. Durch Hinzufügen können Sie die Codierung des Servers verhindern Probleme. Obwohl SQL-Injection bis zu einem gewissen Grad verhindert werden kann, wird die folgende perfekte Lösung dennoch empfohlen.

Die perfekte Lösung besteht darin, PDO und MYSQLi mit dem Prepared Statement-Mechanismus zu verwenden, um mysql_query zu ersetzen (Hinweis: mysql_query ist seit PHP 5.5.0 veraltet und wird in Zukunft verschoben Außer):

PDO:

$pdo = new PDO(&#39;mysql:dbname=dbtest;host=127.0.0.1;charset=utf8&#39;, &#39;user&#39;, &#39;pass&#39;);

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));

foreach ($stmt as $row) {
    // do something with $row
}

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
}

Das Obige stellt vor, wie man SQL-Injection in PHP verhindert. Ich hoffe, dass es für Freunde, die sich für PHP-Tutorials interessieren, hilfreich sein wird.

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