2010-01-05 2 views
8

У меня есть SQL утверждение, аналогичное показанному ниже в Perl:Как избежать одиночных и двойных кавычек в подготовленном операторе SQL?

my $sql="abc..TableName '$a','$b' "; 

$ A бесплатно текст, который может содержать все, включая одинарные кавычки, двойные кавычки, фоны и передний слэш символы и т.д.

Как эти символы могут быть экранированы, чтобы заставить инструкцию SQL работать?

Спасибо.

+3

'$ a' и' $ b' имеют особое значение, относящееся к функции 'sort'. Обычно их не рекомендуется использовать. За исключением коротких имен переменных в образце кода. – daotoad

+0

Кроме тега [perl], dup [Лучший способ остановить SQL Injection в PHP] (http://stackoverflow.com/q/60174/90527). Единственное практическое различие заключается в образцах кода. Кроме того, dup [Что лучший способ избежать атак SQL-инъекций?] (Http://stackoverflow.com/q/1973/). – outis

ответ

21

Вы можете использовать либо ->quote метод (предполагается, что вы используете DBI):

my $oldValue = $dbh->quote('oldValue'); 
my $newValue = $dbh->quote('newValue'); 
$dbh->do("UPDATE myTable SET myValue=$newValue where myValue=$oldValue"); 

еще лучше, лучшая практика заключается в использовании значений связывания:

my $sth = $dbh->prepare('UPDATE myTable SET myValue=? WHERE myValue=?'); 

$sth->execute('newValue','oldValue'); 

Это также должно работать для вызовов хранимых процедур, при условии, что оператор, когда строки были расширены, является действительным SQL. Это может быть конкретный драйвер/БД, поэтому YMMV.

my $sth = $dbh->prepare("DBName..ProcName ?,? "); 
$sth->execute($a, $b); 
+0

Прошу прощения за то, что я не понимаю. Я делаю вызов хранимой процедуры. Пример должен был выглядеть примерно так: my $ sql = "DBName..ProcName '$ a', '$ b'"; – Sam

+5

Использование параметров привязки должно по-прежнему работать для вызовов хранимых процедур. – mopoke

+0

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

9

Используйте подготовленное заявление. Замените переменную на. Чтобы вырезать пример из файлов DBI:

$sql = 'SELECT * FROM people WHERE lastname = ?'; 
$sth = $dbh->prepare($sql); 
$sth->execute($user_input_here); 

Интерполируя вход пользователя в ваш SQL, запрашивается наличие дыр в безопасности.

+0

Прошу прощения за то, что не ясна. Я делаю вызов хранимой процедуры. Пример должен был выглядеть примерно так: my $ sql = "DBName..ProcName '$ a', '$ b'"; – Sam

6

Если вы используете заполнители параметров запроса, вам не нужно избегать содержимого строк.

my $sql="DBName..ProcName ?, ?"; 
$sth = $dbh->prepare($sql); 
$sth->execute($a, $b); 

Если DBI использует истинные параметры запроса, он посылает значение параметров в RDBMS отдельно от заявления SQL. Значения никогда не сочетаются с строкой оператора SQL, поэтому значения никогда не имеют возможности вызвать SQL-инъекцию.

Если DBI является «эмуляцией» подготовленных операторов путем интерполяции переменных в строку запроса, то DBI должен обрабатывать правильную логику экранирования, поэтому вам не нужно. Пусть эксперты (те, кто пишет и тестируют DBI) беспокоятся о том, как это сделать.

3

Если вы не хотите использовать -> котировка (по какой-то причине, эта функция не работает на моей версии DBI), то попробуйте следующее:

$query=~s/\"/\\\"/g; 

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

Кажется, все отлично работает ...!

Смежные вопросы