Как я могу избежать одинарных и двойных кавычек в подготовленном SQL-выражении? - PullRequest
8 голосов
/ 05 января 2010

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

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

$ a - это свободный текст, который может содержать что угодно, включая одинарные кавычки, двойные кавычки, символы обратной и передней косой черты и т. Д.

Как можно экранировать эти символы, чтобы оператор SQL работал?

Спасибо.

Ответы [ 4 ]

21 голосов
/ 05 января 2010

Вы можете использовать метод ->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);
9 голосов
/ 05 января 2010

Используйте готовое утверждение. Замените переменную на? Чтобы написать пример с man-страниц DBI:

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

Интерполяция пользовательского ввода в SQL требует дыр в безопасности.

6 голосов
/ 05 января 2010

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

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

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

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

3 голосов
/ 06 января 2010

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

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

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

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

...