2013-06-03 2 views
1

В настоящее время я пишу приложение, требующее надежной защиты от SQL-инъекции. Мой вопрос таков. Является абсолютным требованием отделить ваши входные параметры от вашего оператора подготовки, чтобы предотвратить SQL-инъекцию, или вы можете просто подготовить какое-либо заявление, чтобы гарантировать, что он свободен от SQL-инъекций?mysqli_prepare как проверка, чтобы предотвратить SQL Injection

Другими словами, можно ли использовать mysqli_prepare как простую проверку, чтобы убедиться, что в запросе, который я ранее построил, нет введенного SQL? Или весь процесс привязки параметров и использование последующих структур операторов, возвращаемых для обработки информации, возвращаемой с сервера?

+4

[Великий эскапизм (или: что вам нужно знать, чтобы работать с текстом в тексте)] (http://kunststube.net/escapism/) – deceze

+0

@deceze хорошая серия статей у вас там ... была просто глядя на них прошлой ночью – Orangepill

+1

[Должны ли вы использовать подготовленные операторы только для их экранирования?] (http://stackoverflow.com/a/16365669/285587) –

ответ

2

Является ли это абсолютное требование, чтобы отделить входные параметры от вашей подготовки заявления, чтобы предотвратить SQL-инъекции

Более или менее.

Существуют и другие методы, которые вы можете использовать для защиты себя, а иногда вы должны их использовать, но 9 раз из 10 с использованием ? в подготовленном заявлении является самым простым, ясным и в целом лучшим решением.

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

№ п. Если вы собрали данные пользователя вместе, чтобы создать вредоносный SQL перед подготовкой инструкции, то подготовка инструкции не даст вам никакой защиты вообще.

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

+0

Что вы говорите, так это то, что если он конструирует запрос перед вводом его в подготовленное заявление, он все равно уязвим для SQL-инъекции - это правда. – crush

2

Подготовка инструкции - это что-то, что делает двигатель SQL. Вы отправляете запрос на сервер раньше времени, говорят:

Prepare : SELECT id, x FROM y WHERE id = ? 

Затем ? будет привязан к данным; ваш уровень абстракции может даже сильно набирать это значение (PDO может это сделать, поскольку вы можете сделать его явным приложением до форматирования и ввода данных).

В процессе подготовки данные и заявления (запросы) хранятся полностью отдельно. Запрос ожидает на сервере, готовый к вызову, и если будут присутствовать поля данных, он будет ожидать ввода.

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

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

+1

В качестве примечания, заполнители всегда строго типизированы. Если тип не указан, они обычно по умолчанию используют строку в моем опыте, которая, конечно же, обрабатывается для защиты от инъекции с помощью механизма SQL. – crush

+0

@crush PDO по умолчанию имеет значение «PDO :: PARAM_STR» при передаче переменных, а mysqli, по-видимому, по умолчанию также содержит строку – Amelia

+0

. Имеет смысл, что они будут по умолчанию для строки, поскольку строка наиболее легко злоупотребляется. – crush

2

Если вы имеете в виду что-то вроде:

$sql = "SELECT foo FROM bar WHERE baz = '$var'"; 
$query = $db->prepare($sql); 
// Wee, we are safe! 

Тогда: NO.

Предполагая $var содержит следующее:

Robert'; DROP TABLE users; -- 

Значение $sql будет:

SELECT foo FROM bar WHERE baz = 'Robert'; DROP TABLE users; --' 

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

+2

также, вероятно, стоит упомянуть, что ''OR 1 = 1; - 'лучше в качестве примера, потому что многозадачность в наши дни почти ушла. – Amelia

+2

Мех, мне просто нравится Bobby Tables в качестве примера. : -3 – deceze

0

Рекомендуется использовать подготовленные операторы, когда параметры отправляются на сервер. Не существует причины. И это абсолютный минимум, который вы можете сделать, чтобы предотвратить инъекцию SQL.

Конечно, если параметры не отправляются, SQL-инъекция не является проблемой.

+1

иногда простой запрос на материал без ввода пользователя намного проще поддерживать и писать, но это исключение из правила. – Amelia

+1

Это правда, но на самом деле это не ответ на вопрос о предотвращении SQL-инъекции. Если нет параметров, которые отправляются, то в первую очередь нет SQL-инъекции. – Barmar

+0

обновил мой ответ. – Aris

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