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

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

mysql_real_escape_string()

на основе документации он избегает следующих символов:


n
r

'
"
Z

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

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

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

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

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

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

6 ответов


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

  • В нуль в ASCII (0х00) характер.
  • \' одиночная кавычка ("'") характер.
  • \" двойные кавычки (""") характер.
  • \b символ backspace.
  • \n символ новой строки (linefeed).
  • \r символ возврата каретки.
  • \t вкладка характер.
  • \Z ASCII 26 (Control-Z). См. Примечание после таблицы.
  • \ обратная косая черта ("\") характер.
  • \% A"%" характер. См. Примечание после таблицы.
  • \_ A"

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

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

вы cat файл, видите, что все в порядке, и просто передайте файл в 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, которую вы не видели, потому что на выходе консоли backspaces перезаписали ее. БАМ!

просто предположение, хотя.

Edit (не смог удержаться):

alt text


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

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

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


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

Это довольно примечательный факт, что до сих пор большинство пользователей считают, что это пользовательский ввод надо бежать, а такое бегство "предотвращает инъекций".


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();
}

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

например: $input =~ s/\'|\"//g;