Какие символы должны быть экранированы, чтобы предотвратить (мои)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 (не смог удержаться):
черный список (определение плохих символов) никогда не будет идти, если у вас есть какие-либо другие варианты.
вам нужно использовать комбинацию белого списка и, что более важно, подходов с привязкой параметров.
хотя этот конкретный ответ имеет фокус 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;