Передача строки, содержащей специальные символы в базу данных [duplicate]

Существует альтернативное решение с анимацией css для скрытого скрытого:

.dropdown{   
  position: relative;
  width: 100%;
 -webkit-animation-name: animatetop;
 -webkit-animation-duration: 0.4s;
 animation-name: animatetop;
 animation-duration: 0.4s
}
/* Add Animation */
@-webkit-keyframes animatetop {
 from {top:-300px; opacity:0} 
 to {top:0; opacity:1}
}

@keyframes animatetop {
 from {top:-300px; opacity:0}
 to {top:0; opacity:1}
}
64
задан kelunik 9 October 2015 в 08:23
поделиться

12 ответов

Ссылки, которые я опубликовал в моих комментариях к вопросу, очень хорошо объясняют проблему. Я обобщил свои чувства по поводу того, почему проблема сохраняется, ниже:

  1. Те, кто только начинает, могут не знать о введении SQL.
  2. Некоторые из них знают о SQL-инъекции, но считайте, что побег - это (только?) решение. Если вы выполните быстрый поиск в Google php mysql query, первая страница появится на странице mysql_query , на которой есть пример, который отображает интерполяцию экранированного пользовательского ввода в запрос. Нет никакого упоминания (по крайней мере, не того, что я могу видеть) вместо использования подготовленных инструкций. Как говорили другие, существует так много учебных пособий, которые используют интерполяцию параметров, что не удивительно, как часто она все еще используется.
  3. Недостаточное понимание того, как работают параметризованные утверждения. Некоторые считают, что это просто фантастическое средство избежать ценностей.
  4. Другие знают о параметризованных утверждениях, но не используют их, потому что слышали, что они слишком медленны. Я подозреваю, что многие люди слышали, как невероятно медленные фразовые высказывания, но на самом деле не проводили никаких собственных испытаний. Как отметил Билл Карвин в своем выступлении, разница в производительности редко должна использоваться в качестве фактора при рассмотрении использования подготовленных заявлений. Преимущества готовятся один раз, выполняют многие , часто, как представляется, забываются, также как и улучшения безопасности и надежности кода.
  5. Некоторые используют параметризованные утверждения везде, но с интерполяцией непроверенных такие как имена таблиц и столбцов, ключевые слова и условные операторы. Динамические поиски, такие как те, которые позволяют пользователям указывать несколько разных полей поиска, условия сравнения и порядок сортировки, являются яркими примерами этого.
  6. Ложное чувство безопасности при использовании ORM. ORM все еще допускают интерполяцию частей инструкции SQL - см. [5].
  7. Программирование - большой и сложный вопрос, управление базами данных - большой и сложный вопрос, безопасность - большой и сложный вопрос. Разработка защищенного приложения базы данных непросто - даже опытные разработчики могут быть обнаружены.
  8. Многие ответы на stackoverflow не помогают. Когда люди пишут вопросы, которые используют динамический SQL и интерполяцию параметров, часто возникает нехватка ответов, которые предполагают использование параметризованных утверждений. В некоторых случаях у меня были люди, опровергающие мое предложение использовать подготовленные заявления - обычно из-за воспринимаемых неприемлемых служебных расходов. Я серьезно сомневаюсь, что те, кто задает большинство этих вопросов, находятся в положении, когда дополнительные несколько миллисекунд, принятые для подготовки параметризованного заявления, окажут катастрофическое влияние на их применение.
53
ответ дан Mike 28 August 2018 в 04:57
поделиться

Хороший вопрос. Ответ более стохастичен, чем детерминированный, и я попытаюсь объяснить свое мнение, используя небольшой пример.

В сети много ссылок, которые предлагают нам использовать параметры в наших запросах или использовать хранимую процедуру с параметрами чтобы избежать SQL Injection (SQLi). Я покажу вам, что хранимые процедуры (например) не являются волшебной палочкой против SQLi. Ответственность по-прежнему остается у программиста.

Рассмотрим следующую хранимую процедуру SQL Server, которая выведет строку пользователя из таблицы «Пользователи»:

create procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
declare @sql as nvarchar(512)
set @sql = 'select usrID, usrUName, usrFullName, usrRoleID '+
           'from Users '+
           'where usrUName = '''+@name+''' and usrPass = '''+@pass+''''
execute(@sql)

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

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [dbo].[getUser] 
   @name = 'admin'
  ,@pass = '!@Th1siSTheP@ssw0rd!!'
GO

Но здесь у нас плохой метод программирования, используемый программистом внутри хранимой процедуры, поэтому злоумышленник может выполнить следующее:

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [TestDB].[dbo].[getUser] 
   @name = 'admin'
  ,@pass = 'any'' OR 1=1 --'
GO

Вышеуказанные параметры будут переданы в качестве аргументов хранимой процедуры, а команда SQL, которая в конечном итоге будет выполнена, будет:

select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = 'admin' and usrPass = 'any' OR 1=1 --'

. , который получит все строки от пользователей

. Проблема в том, что даже мы следуем принципу «Создаем хранимую процедуру и передаем поля для поиска в качестве параметров», SQLi все еще выполняется. Это связано с тем, что мы просто копируем нашу плохую практику программирования внутри хранимой процедуры. Решение этой проблемы состоит в том, чтобы переписать нашу Хранимую процедуру следующим образом:

alter procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = @name and usrPass = @pass

То, что я пытаюсь сказать, заключается в том, что разработчики должны сначала узнать, что такое SQLi-атака, и как ее можно выполнить, а затем соответственно защищать их код. Слепо следовать «лучшим практикам» - это не всегда безопасный способ ... и, возможно, именно поэтому у нас так много «лучших практик» - не удается!

8
ответ дан Andreas Venieris 28 August 2018 в 04:57
поделиться

Да, использование подготовленных операторов останавливает все инъекции SQL, по крайней мере теоретически. На практике параметризованные операторы могут быть не реальными подготовленными операциями, например. PDO в PHP имитирует их по умолчанию, поэтому открыт для атаки кромки кромки .

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

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

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

5
ответ дан Community 28 August 2018 в 04:57
поделиться

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

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

Чаще всего разработчики неправильно используют эту функцию. Обычно код выглядит примерно так, когда выполняется правильно:

db.parameterize_query("select foo from bar where baz = '?'", user_input)

Некоторые разработчики объединяют строки вместе, а затем используют параметризованный запрос, который фактически не делает вышеупомянутое разграничение данных / кода, обеспечивающее безопасность которые мы ищем:

db.parameterize_query("select foo from bar where baz = '" + user_input + "'")

Правильное использование параметризованных запросов обеспечивает очень прочную, но непроницаемую защиту от атак SQL-инъекций.

1
ответ дан Daniel Crowley 28 August 2018 в 04:57
поделиться

Я избегаю абсолютов в программировании; всегда есть исключение. Я настоятельно рекомендую хранимые процедуры и объекты команд. Большая часть моей базы с SQL Server, но я играю с MySql время от времени. Существует множество преимуществ хранимых процедур, включая кэшированные планы запросов; да, это может быть достигнуто с помощью параметров и встроенного SQL, но это открывает больше возможностей для инъекционных атак и не помогает с разделением проблем. Для меня также намного проще защитить базу данных, поскольку мои приложения обычно имеют только разрешение на выполнение указанных хранимых процедур. Без прямого доступа к таблицам и представлениям гораздо сложнее вводить что-либо. Если пользователь приложений скомпрометирован, у него есть только разрешение на выполнение того, что было предварительно определено.

Мои два цента.

3
ответ дан Derek 28 August 2018 в 04:57
поделиться

Поскольку большинство кодеков не написано с учетом безопасности и управления, учитывая выбор между добавлением функций (особенно что-то видимое, которое можно продать) и безопасностью / стабильностью / надежностью (что гораздо труднее продать), они будут почти неизменно выбирают первое. Безопасность является лишь проблемой, когда она становится проблемой.

2
ответ дан evil otto 28 August 2018 в 04:57
поделиться

Чтобы защитить приложение от SQL-инъекции, выполните следующие шаги:

Шаг 1. Ограничьте ввод. Шаг 2. Используйте параметры с хранимыми процедурами. Шаг 3. Используйте параметры с динамическим SQL.

См. http://msdn.microsoft.com/en-us/library/ff648339.aspx

1
ответ дан Fahad Hussain 28 August 2018 в 04:57
поделиться

, даже если подготовленные утверждения правильно используются во всем собственном коде веб-приложения, ошибки SQL-инъекции могут все еще существовать, если компоненты кода базы данных строят запросы с пользовательского ввода небезопасным образом. Ниже приведен пример хранимой процедуры, которая уязвима для SQL-инъекции в параметре @name:

CREATE PROCEDURE show_current_orders
(@name varchar(400) = NULL)
AS
DECLARE @sql nvarchar(4000)
SELECT @sql = ‘SELECT id_num, searchstring FROM searchorders WHERE ‘ +
‘searchstring = ‘’’ + @name + ‘’’’;
EXEC (@sql)
GO

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

0
ответ дан Hadid Graphics 28 August 2018 в 04:57
поделиться

Когда в статьях рассказывается о параметризованных запросах, останавливающих атаки SQL, они на самом деле не объясняют, почему это часто бывает так: «Это так, поэтому не спрашивайте, почему» - возможно, потому что они сами не знают. Верным признаком плохого педагога является тот, который не может признать, что он ничего не знает. Но я отвлекся. Когда я говорю, я понял, что совершенно понятно, что меня путают просто. Представьте себе динамический SQL-запрос

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

, поэтому простая инсталляция sql должна была просто ввести имя пользователя в качестве «OR 1 = 1». Это действительно сделало бы запрос sql:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

В этом заявлении указывается, что все клиенты, где они являются, являются пустыми ('') или 1 = 1, что является логическим, приравнивая true. Затем он использует - чтобы прокомментировать остальную часть запроса. Таким образом, это будет просто распечатывать всю таблицу клиентов или делать с ней все, что вы захотите, если он войдет в систему, он войдет в систему с привилегиями первого пользователя, которые часто могут быть администратором.

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

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'

parameters.add("User", username)
parameters.add("Pass", password)

, где имя пользователя и пароль являются переменными, указывающими на связанное введенное имя пользователя и пароль

. Теперь вы можете думать, что это ничего не меняет. Конечно, вы все равно могли бы просто ввести в поле имени пользователя что-то вроде Nobody OR 1 = 1 '-, эффективно выполнив запрос:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

И это похоже на действительный аргумент. Но вы ошибаетесь.

Способ работы с параметризованными запросами заключается в том, что sqlQuery отправляется как запрос, и база данных точно знает, что будет делать этот запрос, и только после этого он будет вставлять имя пользователя и пароли просто как ценности. Это означает, что они не могут выполнить запрос, потому что база данных уже знает, что будет делать запрос. Таким образом, в этом случае он будет искать имя пользователя «Nobody OR 1 = 1 '-» и пустой пароль, который должен выглядеть ложным.

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

32
ответ дан Josip Ivic 28 August 2018 в 04:57
поделиться

Я бы не сказал «тупой».

Я думаю, что это проблемы. Большинство учебников по SQL, книги, все, что объясняет SQL со встроенными значениями, вообще не упоминают параметры привязки. Люди, изучающие эти учебные пособия, не имеют возможности изучить его правильно.

2
ответ дан Markus Winand 28 August 2018 в 04:57
поделиться

Сначала мой ответ на ваш первый вопрос: Да, насколько я знаю, с помощью параметризованных запросов SQL-инъекции больше не будут возможны. Что касается ваших следующих вопросов, я не уверен и могу только рассказать вам о причинах:

Я думаю, что проще «просто» написать строку запроса SQL, объединив некоторые разные части (возможно, даже зависимые на некоторых логических проверках) вместе со значениями, которые нужно вставить. Он просто создает запрос и выполняет его. Другим преимуществом является то, что вы можете печатать (эхо, вывод или что-то еще) строку запроса sql, а затем использовать эту строку для ручного запроса к движку базы данных.

При работе с подготовленными операторами вы всегда имеете как минимум еще один шаг: вам нужно построить свой запрос (включая параметры, конечно). Вы должны подготовить запрос на сервере. Вы должны привязать параметры к фактическим значениям, которые вы хотите использовать для своего запроса. Вы должны выполнить запрос .

Это немного больше работает (и не так просто программировать), особенно для некоторых «быстрых и грязных» заданий, которые часто оказываются очень долговечными ...

С наилучшими пожеланиями ,

Коробка

2
ответ дан TomS 28 August 2018 в 04:57
поделиться

Может ли параметризованный оператор остановить всю инъекцию SQL?

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

Вот почему я сделал свою Mysql-оболочку для PHP, которая поддерживает большинство литералов, которые могут быть добавлены в запрос динамически, включая массивы и идентификаторы.

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

Как вы можете видеть, на самом деле просто невозможно, чтобы все задавали ваши запросы, даже если вы «Не тупой.

2
ответ дан Your Common Sense 28 August 2018 в 04:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: