На самом деле есть два вопроса в одном. И вопрос из заголовка имеет мало общего с опасениями, выраженными ОП в комментариях впоследствии.
Хотя я понимаю, что для OP важен именно их конкретный случай, для читателей из Google важно ответить на более общий вопрос, который можно сформулировать так: «Конкатенация так же безопасна, как и подготовленные утверждения, если я убедился что каждый литерал, который я объединяю, безопасен? ". Итак, я хотел бы сосредоточиться на последнем. И ответ
Определенно нет.
Объяснение не такое прямое, как хотелось бы большинству читателей, но я постараюсь изо всех сил.
Некоторое время я размышлял над этим вопросом, и в результате появилась статья (хотя и основанная на среде PHP), в которой я попытался подвести итоги. Мне пришло в голову, что вопрос защиты от SQL-инъекций часто ускользает от некоторых связанных, но более узких тем, таких как экранирование строк, приведение типов и тому подобное. Хотя некоторые меры можно считать безопасными, если их принимать сами по себе, не существует системы или простого правила, которому следовало бы следовать. Это делает его очень скользким, слишком сильно отнимая у разработчика внимание и опыт.
Вопрос о внедрении SQL нельзя упростить до какой-то конкретной синтаксической проблемы. Он шире, чем раньше думал средний разработчик. Это тоже методологический вопрос. Это не только «какое именно форматирование мы должны применить», но и « как это должно быть сделано».
(С этой точки зрения статья Джона Скита, процитированная в другом ответе, работает скорее плохо, чем хорошо, поскольку она снова придирается к какому-то крайнему случаю, концентрируется на конкретной проблеме синтаксиса и не может решить проблему в целом.)
Когда вы пытаетесь решить вопрос о защите не в целом, а как набор различных синтаксических проблем, вы сталкиваетесь с множеством проблем.
- список возможных вариантов форматирования действительно огромен. Значит, некоторых можно легко упустить из виду. Или запутайте их (например, используя экранирование строки для идентификатора ).
- Конкатенация означает, что все меры защиты должны выполняться программистом, а не программой. Сама по себе эта проблема приводит к нескольким последствиям:
- такое форматирование выполняется вручную. Ручной означает чрезвычайно высокую вероятность ошибок. Можно было просто забыть подать заявку.
- более того, есть соблазн перенести процедуры форматирования в какую-то централизованную функцию, что еще больше запутает вещи и испортит данные, которые не попадают в базу данных.
- когда задействовано более одного разработчика, количество проблем увеличивается в десять раз.
- когда используется конкатенация, невозможно сразу определить потенциально опасный запрос: все они потенциально опасны!
В отличие от этого беспорядка, заранее подготовленные утверждения - это действительно Святой Грааль:
- его можно выразить в виде одного простого правила, которому легко следовать.
- По сути, это неотъемлемая мера, означающая, что разработчик не может вмешиваться и, вольно или невольно, испортить процесс.
- защита от инъекций на самом деле является лишь побочным эффектом подготовленных операторов, реальная цель которых - создать синтаксически правильный оператор. А синтаксически правильное утверждение на 100% доказано. Тем не менее, нам нужно, чтобы наш синтаксис был правильным, несмотря на любую возможность инъекции.
- при полном использовании он защищает приложение независимо от опыта разработчика. Скажем, есть такая штука , как инъекция второго порядка . И очень сильное заблуждение, которое гласит: «Чтобы защитить, избегайте всех вводимых пользователем данных ». Вместе они приводят к инъекции, если разработчик решает, что нужно защитить, а что нет.
(Подумав дальше, я обнаружил, что текущего набора заполнителей недостаточно для реальных жизненных потребностей, и его необходимо расширять как для сложных структур данных, таких как массивы, так и даже для ключевых слов или идентификаторов SQL, которые иногда приходится добавлять к запрос тоже динамически, но разработчик остается безоружным для такого случая и вынужден вернуться к конкатенации строк, но это уже другой вопрос).
Интересно, что полемика по этому вопросу вызвана очень противоречивой природой Stack Overflow. Идея сайта состоит в том, чтобы использовать конкретные вопросы пользователей, которые задают напрямую, для достижения цели создания базы данных ответов общего назначения, подходящей для пользователей, которые приходят из поиска . Идея сама по себе неплохая , но она терпит неудачу в такой ситуации: когда пользователь задает очень узкий вопрос , в частности, чтобы получить аргумент в споре с коллегой (или решить, стоит ли рефакторинг кода). Хотя большинство опытных участников пытаются написать ответ, помня о миссии Stack Overflow в целом, что делает их ответ интересным для как можно большего числа читателей, а не только для OP.