Какие символы нужно экранировать, чтобы предотвратить (My) SQL-инъекции?

Я использую функцию MySQL API

mysql_real_escape_string()

Согласно документации, он экранирует следующие символы:

\0
\n
\r
\
'
"
\Z

Теперь я заглянул в библиотеку безопасности ESAPI OWASP.org, и в порте Python у нее был следующий код (http://code.google.com/p/owasp-esapi-python/source/browse/esapi/codecs/mysql.py):

        """
        Encodes a character for MySQL.
        """
        lookup = {
        0x00 : "\\0",
        0x08 : "\\b",
        0x09 : "\\t",
        0x0a : "\\n",
        0x0d : "\\r",
        0x1a : "\\Z",
        0x22 : '\\"',
        0x25 : "\\%",
        0x27 : "\\'",
        0x5c : "\\\\",
        0x5f : "\\_",
        }

Теперь мне интересно, действительно ли нужно убегать от всех этих персонажей. Я понимаю, почему там% и _, это метасимволы в операторе LIKE, но я просто не могу понять, почему они добавили символы возврата и табулятора (\ b \ t)? Есть ли проблема с безопасностью, если вы выполните запрос:

SELECT a FROM b WHERE c = '...user input ...';

Где пользовательский ввод содержит табуляторы или символы возврата?

У меня вопрос: почему они включили \ b \ t в библиотеку безопасности ESAPI? Есть ли какие-нибудь ситуации, когда вам может потребоваться экранировать эти символы?


person Tower    schedule 06.07.2009    source источник
comment
Я не питон или MySql, но я сначала искал модульные тесты для этого, к сожалению, они не обнаружили ничего полезного - code.google.com/p/owasp-esapi-python/source/browse/esapi/test/   -  person RichardOD    schedule 06.07.2009


Ответы (6)


На странице MySQL для строк говорится:

  • \0 Символ ASCII NUL (0x00).
  • \' Символ одинарной кавычки («'»).
  • \" Символ двойной кавычки («"»).
  • \b Символ возврата.
  • \n Символ новой строки (перевода строки).
  • \r Символ возврата каретки.
  • \t Символ табуляции.
  • \Z ASCII 26 (Control-Z). См. Примечание после таблицы.
  • \\ Символ обратной косой черты («\»).
  • \% Символ «%». См. Примечание после таблицы.
  • \_ Символ «_». См. Примечание после таблицы.
person Gumbo    schedule 06.07.2009
comment
Ссылка мертва. Рассмотрите возможность обновления. - person mR_fr0g; 30.04.2014
comment
Это не отвечает на ту часть вопроса, где спрашивается, почему? - person The Godfather; 28.06.2019
comment
Имейте в виду, что вы, вероятно, не хотите всегда экранировать % и _, поскольку обратная косая черта будет передана буквально, если она не используется в контексте фильтра / поиска, например \% будет выглядеть как строка \% при использовании = и % при использовании like - person Brian Leishman; 16.09.2019

Предположение относительно символа возврата: представьте, что я отправляю вам электронное письмо «Привет, вот запрос на обновление вашей БД, как вы хотели» и прикрепленный текстовый файл с

INSERT INTO students VALUES ("Bobby Tables",12,"abc",3.6);

Вы загружаете файл, видите, что все в порядке, и просто перенаправляете файл в MySQL. Однако вы не знали, что я поставил

DROP TABLE students;\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b

перед INSERT STATEMENT, которого вы не видели, потому что на выходе консоли backspaces перезаписали его. Бамм!

Но это только предположение.

Изменить (не удержался):

alt text

person balpha    schedule 06.07.2009
comment
Спасибо, Стефано, что выполняет пункт об авторстве лицензии CC. - person balpha; 06.07.2009

Внесение в черный список (выявление плохих символов) никогда не поможет, если у вас есть другие варианты.

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

Хотя этот конкретный ответ ориентирован на PHP, он по-прежнему помогает и поможет объяснить, что простое выполнение строки через фильтр char во многих случаях не работает. Пожалуйста, см. Сохраняйте ли htmlspecialchars и mysql_real_escape_string мои PHP-код защищен от инъекций?

person Cheekysoft    schedule 06.07.2009

Где пользовательский ввод содержит табуляторы или символы возврата?

Примечательно то, что до сих пор большинство пользователей считают, что это ввод пользователя нужно экранировать, и такое экранирование «предотвращает инъекции».

person Your Common Sense    schedule 01.05.2014

Решение Java:

public static String filter( String s ) {
    StringBuffer buffer = new StringBuffer();
    int i;

    for( byte b : s.getBytes() ) {
        i = (int) b;

        switch( i ) {
            case  9 : buffer.append( "    " ); break;
            case 10 : buffer.append( "\\n"  ); break;
            case 13 : buffer.append( "\\r"  ); break;
            case 34 : buffer.append( "\\\"" ); break;
            case 39 : buffer.append( "\\'"  ); break;
            case 92 : buffer.append( "\\"   );

            if( i > 31 && i < 127 ) buffer.append( new String( new byte[] { b } ) );
        }
    }

    return buffer.toString();
}
person crae    schedule 09.09.2017

нельзя просто удалить одиночные кавычки из пользовательского ввода?

eg: $input =~ s/\'|\"//g;

person Jarett L    schedule 13.03.2017
comment
Если вы пытаетесь сохранить имя, как О'Лири, вы испортите имя человека. Если вы сохраняете предложение типа "Help!", David yelled., вам следует оставить двойные кавычки. Так что да, в некоторых случаях сброс специальных символов может быть приемлемым, но не во всех случаях. - person Bing; 10.03.2018