出于为后人栽树而不是挖坑的考虑,给出PHP以及MYSQL的版本信息,以免将来“问题”不再是“问题”了。
立即学习“PHP免费学习笔记(深入)”;
注意:虽然在MYSQL5.5.37-log下该Trick已经被修复了,但仍然没有确切地解决注入问题,介于很多公司的系统仍在使用Mysql5.0,我建议立马做出改进,这点也是我《也说说几种让程序员快速提高能力的方法 》中提到的一个十分重要的点。
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"
注意:第三个mysql_real_escape_string之所以能够防注入是因为mysql_escape_string本身并没办法判断当前的编码,必须同时指定服务端的编码和客户端的编码,加上就能防编码问题的注入了。虽然是可以一定程度上防止SQL注入,但还是建议以下的完美解决方案。
$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
}以上就介绍了PHP防SQL注入不要再用addslashes和mysql_real_escape_string了,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号