Heim > Artikel > Backend-Entwicklung > Um SQL-Injection in PHP zu verhindern, verwenden Sie keine Addslashes und mysql_real_escape_string mehr.
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.
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 „.
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('servername','username','password'); mysql_select_db("test"); mysql_query("SET NAMES GBK"); $_POST['username'] = chr(0xbf).chr(0x27).' OR username = username /*'; $_POST['password'] = 'guess'; $username = addslashes($_POST['username']); $password = addslashes($_POST['password']); $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $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['username']); $password = mysql_real_escape_string($_POST['password']); $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $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['username']); $password = mysql_real_escape_string($_POST['password']); $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $result = mysql_query($sql) or trigger_error(mysql_error().$sql); var_dump(mysql_num_rows($result)); var_dump(mysql_client_encoding());
PHP version: 5.2.5 int(3) string(6) "latin1" int(3) string(6) "latin1" int(0) string(3) "gbk"
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.
$pdo = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass'); $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.