Пользовательский ввод SQL-экранирования - PullRequest
1 голос
/ 08 апреля 2009

Можете ли вы дать мне совет? Я искал вопросы, но не нашел ничего похожего на мое.

Как сделать так, чтобы мои пользовательские входы автоматически экранировались, когда они предназначены для использования в запросах SQL? Мне не нравится в моем коде, заполненном чем-то вроде

$var_x = $DB->Escape($_POST['var_x']);
$another_var = $DB->Escape($_POST['another_var']);
$some_string = $DB->Escape($_POST['some_string']);
...

Предполагается, что у меня есть класс базы данных с методом Escape, который выполняет mysql_real_escape_string

Но я не могу установить автоматический экранирование и для SQL-запроса, потому что он прерывает запросы вставки:

function Exec($sql){
   $result = mysql_query($this->Escape($sql));
}

$q = $DB->Exec("SELECT * FROM table WHERE id = 'xxx'");

Это делает их \ "ххх \". что неверно.

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

Короче говоря - как сделать умный автоматический экранирование, которое работает со всем запросом и экранирует только значения?

Ответы [ 4 ]

4 голосов
/ 08 апреля 2009

Фактически, единственное, что вы должны учитывать (мы не говорим здесь о тестовых проектах, очевидно), это использовать параметризованные операторы. Это единственный способ (когда SQL Synax допускает их, конечно). При правильном выполнении это не сделает вашу систему более сложной, но сделает более надежной.

2 голосов
/ 08 апреля 2009

Извините, вы не можете ничего авто. Когда вы объединяете строки, у вас всегда будут проблемы с экранированием символов; это не то, что вы можете «решить» один раз, и вам больше никогда не придется думать об этом.

Если вы делаете:

$a= "a'b";
$query= "SELECT * FROM things WHERE name='$a'";

Тогда ваша строка запроса содержит как апострофы, которые являются настоящими апострофами в строковых литералах, так и апострофы, которые являются разделителями строк:

SELECT * FROM things WHERE name='a'b'

Нужно сбежать; другой не должен. Как вы можете сказать, что есть что? Вы не можете, эта информация потеряна навсегда. Вместо этого вы должны сказать:

$query= "SELECT * FROM things WHERE name='".mysql_real_escape_string($a)."'";

(или какая-либо другая escape-функция больше подходит для используемой вами базы данных).

Гадкий? Черт возьми да Вот почему мы используем параметризованные запросы. Это избавляет от конкатенации строк со всеми своими проблемами.

Конкатенация строк выглядит просто. Люди думают, что они понимают, что такое засорение. Но на самом деле это не так.

1 голос
/ 08 апреля 2009

Я использую этот метод:

$db->set('name',$name);
$db->set('title',$title);
$db->insert('users');

Здесь метод $db->set() автоматически экранирует значение (т. Е. Второй аргумент).

С PHP 5 вы также можете сделать это:

$db->set('name',$name)->set('title',$title)->insert('users');
0 голосов
/ 08 апреля 2009

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

Не хотите объяснить ваше утверждение, что параметризованные запросы являются "более сложными"? Я не объединяю внешние данные в запросы - когда-либо - и это самая простая вещь в мире, а также то, что я гораздо ближе к "пуленепробиваемым" способам, чем любая техника экранирования.

...