Как экранировать кавычки в sql oracle

Обновлено: 05.07.2024

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

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

Мы используем Microsoft SQL Server 2000, для которого, как мне кажется, одинарная кавычка является единственным разделителем строк и единственным способом избежать строкового разделителя, поэтому нет способа выполнить что-либо, введенное пользователем.

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

Что не так с этим кодом? Есть ли способ получить атаку SQL-инъекций после этой техники очистки? Пример пользовательского ввода, который использует эту технику, был бы очень полезен.

Я до сих пор не знаю ни одного способа эффективно запустить атаку SQL-инъекцией на этот код. Несколько человек предположили, что обратная косая черта будет выходить из одной одинарной кавычки и оставлять другую для завершения строки, так что остальная часть строки будет выполнена как часть команды SQL, и я понимаю, что этот метод будет работать для внедрения SQL в база данных MySQL, но в SQL Server 2000 единственный способ (который мне удалось найти) избежать одиночной кавычки - это другая одинарная кавычка; обратная косая черта не сделает этого.

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

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

ОТВЕТЫ

Ответ 1

Прежде всего, это просто плохая практика. Валидация входных данных всегда необходима, но она также всегда iffy.
Хуже того, проверка черного списка всегда проблематична, гораздо лучше явно и строго определять, какие значения/форматы вы принимаете. По общему признанию, это не всегда возможно, но в какой-то мере это всегда нужно делать. Некоторые исследовательские работы по теме:

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

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

Правильный способ сделать это:

  • Валидация белого списка: тип, длина, формат или принятые значения
  • Если вы хотите попасть в черный список, идите прямо вперед. Цитата escaping хороша, но в контексте других смягчений.
  • Использовать объекты Command и Parameter для подготовки и проверки
  • Запросить только параметризованные запросы.
  • Еще лучше, используйте только хранимые процедуры.
  • Избегайте использования динамического SQL и не используйте конкатенацию строк для создания запросов.
  • Если вы используете SP, вы также можете ограничить разрешения в базе данных только для выполнения необходимых SP, а не напрямую обращаться к таблицам.
  • вы также можете легко убедиться, что вся база кода только обращается к БД через SP.

Ответ 2

Хорошо, этот ответ будет связан с обновлением вопроса:

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

Теперь, помимо сбрасывания обратного слэша MySQL, и принимая во внимание, что мы на самом деле говорим о MSSQL, на самом деле существует 3 возможных способа по-прежнему SQL-инъекции вашего кода

sSanitizedInput = "'" и заменить (sInput, "'" , "''" ) и "'"

Учтите, что они не все будут действительны во все времена и очень зависят от вашего фактического кода вокруг него:

  • SQL Injection второго порядка - если SQL-запрос перестраивается на основе данных, полученных из базы данных после экранирования, данные объединяются без привязки и могут быть косвенно введены SQL. См.
  • Усечение строк - (немного сложнее) - Сценарий: у вас есть два поля, например имя пользователя и пароль, а SQL объединяет их оба. И оба поля (или только первое) имеют жесткий предел по длине. Например, имя пользователя ограничено 20 символами. Скажем, у вас есть этот код:

Тогда то, что вы получаете - это имя пользователя, экранированное, а затем обрезано до 20 символов. Проблема здесь - я буду придерживаться моей цитаты в 20-м символе (например, после 19 а), и ваша экранирующая цитата будет обрезана (в 21-м символе). Затем SQL

в сочетании с вышеупомянутым неверным именем пользователя приведет к тому, что пароль уже будет находиться вне кавычек и будет содержать только полезную нагрузку.
3. Контрабанда Unicode. В определенных ситуациях можно передать высокоуровневый символ юникода, который выглядит как цитата, но не до тех пор, пока он не попадет в базу данных, где это внезапно. Поскольку это не цитата, когда вы проверяете ее, она пройдет легко. См. Мой предыдущий ответ для получения более подробной информации и ссылки на оригинальные исследования.

Ответ 3

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

Ответ 4

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

Один из способов запуска атаки на процедуру "quote the argument" - с усечением строки. Согласно MSDN, в SQL Server 2000 SP4 (и SQL Server 2005 с пакетом обновления 1) слишком длинная строка будет тихо усечена.

При цитировании строки строка увеличивается в размере. Каждый апостроф повторяется. Затем это можно использовать для перемещения частей SQL за пределы буфера. Таким образом, вы можете эффективно урезать части предложения where.

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

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

Я бы рекомендовал перейти с параметрами. Всегда. Просто хочу, чтобы я мог обеспечить это в базе данных. И как побочный эффект, вы, скорее всего, получите больше кеш-хитов, потому что больше заявлений выглядят одинаково. (Это, безусловно, верно для Oracle 8)

Ответ 5

Вводная санитария - это не то, что вы хотите, чтобы наполовину осел. Используйте всю свою задницу. Используйте регулярные выражения в текстовых полях. TryCast ваши численные значения для правильного числового типа и сообщите об ошибке проверки, если он не работает. Очень легко найти шаблоны атаки на вашем входе, например "-. Предположим, что все введенные пользователем данные враждебны.

Ответ 6

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

Недостатком является то, что вам действительно нужно быть уверенным, какие строки содержат пользовательский ввод (всегда потенциально вредоносный) и какие строки являются действительными SQL-запросами. Одна из ловушек - если вы используете значения из базы данных - были ли эти значения первоначально предоставлены пользователем? Если это так, их также следует избегать. Мой ответ состоит в том, чтобы попытаться дезинфицировать как можно позже (но не позже!) При построении SQL-запроса.

Однако в большинстве случаев привязка параметров - это путь - это просто проще.

Ответ 7

Это плохая идея, поскольку вы, кажется, знаете.

Что-то вроде ускорения цитаты в строке:\

Ваша замена приведет к:\''

Если обратная косая черта сбрасывает первую цитату, вторая цитата закончила строку.

Ответ 8

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

Есть способы обойти любой полезный черный список, который вы можете придумать (и некоторые белые списки тоже).

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

Ответ 9

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

Ответ 10

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

Ответ 11

Да, это должно работать до тех пор, пока кто-то не выполнит SET QUOTED_IDENTIFIER OFF и использует двойную кавычку.

Изменить: это не так просто, как не позволить злоумышленнику отключить цитируемые идентификаторы:

Драйвер ODBC для собственного клиента SQL Server и поставщик OLE DB для собственного клиента SQL Server для SQL Server автоматически устанавливают QUOTED_IDENTIFIER в положение ON при подключении. Это можно настроить в источниках данных ODBC, в атрибутах соединения ODBC или в свойствах соединения OLE DB. Значение по умолчанию для SET QUOTED_IDENTIFIER отключено для соединений из приложений DB-Library.

При создании хранимой процедуры настройки SET QUOTED_IDENTIFIER и SET ANSI_NULLS фиксируются и используются для последующих вызовов этой хранимой процедуры.

SET QUOTED_IDENTIFIER также соответствует настройке QUOTED_IDENTIFER для ALTER DATABASE.

SET QUOTED_IDENTIFIER устанавливается во время разбора. Установка во время разбора означает, что если инструкция SET присутствует в пакетной или хранимой процедуре, она вступает в силу независимо от того, действительно ли выполнение кода достигает этой точки; и инструкция SET вступает в силу до выполнения любых операторов.

Там может быть много способов QUOTED_IDENTIFIER, если вы этого не знаете. По общему признанию - это не тот курячий пистолет, который вы ищете, но это довольно большая поверхность атаки. Конечно, если вы также избежали двойных кавычек - тогда мы вернемся туда, где мы начали.;)

Ответ 12

Ваша защита потерпит неудачу, если:

  • запрос ожидает число, а не строку
  • существовал другой способ представления единого кавычки, в том числе:
    • управляющая последовательность, такая как \039
    • символ юникода

    (в последнем случае это должно быть нечто, которое было расширено только после того, как вы заменили)

    Ответ 13

    Патрик, добавляете ли вы одиночные кавычки вокруг ВСЕГО ввода, даже числового ввода? Если у вас есть числовой ввод, но они не помещают одинарные кавычки вокруг него, тогда у вас есть экспозиция.

    Ответ 14

    Какой уродливый код для всех, что санитария пользователя будет! Затем неуклюжий StringBuilder для оператора SQL. Метод подготовленных операторов приводит к значительно более чистым кодам, а преимущества SQL Injection - это действительно приятное дополнение.

    Также зачем изобретать колесо?

    Ответ 15

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

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

    ПРИМЕЧАНИЕ. В вашем методе также предполагается, что все, работающие над вашим приложением, всегда помнят, чтобы дезинформировать входные данные до того, как они попадут в базу данных, что в большинстве случаев, вероятно, нереалистично.

    Ответ 16

    В то время как вы можете найти решение, которое работает для строк, для числовых предикатов вам также нужно убедиться, что они только передают числа (простая проверка может быть проанализирована как int/double/decimal?).

    Это много дополнительной работы.

    Ответ 17

    @BryanH Мне нравится видеть этот ответ: "Посмотрите на ответы ниже и не думайте, что вы можете изобретать велосипед и делать лучше - лучше! --than всех, кто ушел раньше".

    Теперь я прошу вас обратить ваше внимание на беспроводное соединение, которым вы пользуетесь, и на ваш мобильный телефон, и на многие другие. Я не буду утомлять всех подробностями. Они родились в сознании Теслы и улучшились почти через 100 лет. Ты водишь Ford 1912 года? Почему мы хотим, чтобы что-то было улучшено? Читая избиение себя праведными комментариями, вот почему я не размещал и почти не использую этот сайт. Не троллите, если вы не можете дать конструктивную критику и помощь, а затем следуйте старой поговорке: если вы не можете сказать что-то хорошее . если потеряно, попробуйте Google, что-то еще, что было переизобретением старого продукта. Хотелось бы, чтобы рядом с вашим комментарием было пониженное голосование. Приношу свои извинения за разглагольствование всем тем, кто это рассматривает.

    Ответ 18

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

    Ответ 19

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

    вы никогда не позволяете строковым значениям, исходящим от пользователей, становиться чем-то другим, кроме строковых литералов (т.е. избегать настройки конфигурации: "Введите дополнительные имена/выражения столбца SQL здесь:" ). Типы значений, отличные от строк (числа, даты. ): преобразовать их в свои собственные типы данных и предоставить подпрограмму для литерала SQL из каждого типа данных.

    • Операторы SQL являются проблематичными для проверки

    вы используете либо столбцы nvarchar / nchar (и префиксные строковые литералы с помощью N ), либо предельные значения, входящие в столбцы varchar / char только для символов ASCII (например, исключение throw при создании SQL)

    • таким образом вы избежите автоматического преобразования апострофа из CHAR (700) в CHAR (39) (и, возможно, других подобных хакеров Unicode)

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

    • в SQL Server обнаружен известный дефект, позволяющий обойти ошибку SQL, брошенную на усечение (приводящую к молчанию усечения)

    вы гарантируете, что SET QUOTED_IDENTIFIER всегда ON

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

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

    Одной из моих любимых команд SQL являлась QUOTENAME. При программировании генерации кода обычно возникает необходимость заключать строковое значение в кавычки и экранировать любые символы, совпадающие с теми, которыми вы ограничиваете строку, их удвоением. (А если у вас пара таких символов в строке, вам их потребуется уже четыре.) Например, чтобы взять следующую строку в одинарные кавычки ('):


    Чтобы иметь возможность использовать её в динамическом операторе или объявлении переменной, потребуется удвоить одинарную кавычку в строке:


    Или, если вы Rob Volk (@sql_r на Twitter), и хотите создать раздражающую базу данных на вашем лучшем заклятом SQL Server, то, чтобы включить скобки в имя базы типа:


    вам придется сделать так:


    Удваивается закрывающая скобка, но не открывающая. Для экранирования можно использовать QUOTENAME. Параметрами этой функции являются строка и разделитель. По умолчанию удваивается скобка как у большинства имён SQL Server, хотя вы можете использовать любой символ для удвоения. Так для нашей строки:


    Этот код вернет







    objectNamestring
    Mr. O'Malley [Mr. O'Malley] 'Mr. O''Malley'

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


    Выполните этот запрос в Management Studio. Вы увидите на вкладке результата строку, начинающуюся с приведенного выше текста. Проблема состоит в том, что QUOTENAME предназначена для закавычивания значений имен SQL Server, а поскольку в SQL Server имена не могут быть длиннее, чем 128 символов. на входе должно быть не более 128 символов (ниже покажем, что может быть и больше). Итак:


    Когда вход превышает 128 символов, возвращается NULL без каких либо предупреждений. Это, мягко говоря, не то, что вы хотели. В моем случае я разработал генератор скрипта расширенных свойств, который принимает значение типа sql_variant и преобразует его к nvarchar(max). Я не тестировал входы, превышающие 128 символов, но коллега любезно предоставил мне строку размером порядка 8000 символов. К счастью, это не был рабочий сервер, где бы безостановочно звонил телефон поддержки.

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


    Этот код демонстирует один и тот же результат для обоих вариантов.

    Следует заметить, что это (как и любая простая повторно исполняемая скалярная функция) просится для использования в качестве пользовательской функции. В версиях, предшествующих 2019, всегда однозначно советовали избегать их, т.к. они, мягко говоря, ограничивали производительность. В одних случаях падение производительности было незначительным, в других - существенными провалами. В SQL Server 2019 Microsoft изменила механизм выполнения некоторых скалярных функций, который будет "встраивать" код функции в план запроса, использующего эту функцию. В результате производительность, полученная для перекодируемого оператора и при использовании функции соизмеримы (даже для довольно сложных функций!).

    Построим, например, в базе данных WideWorldImporters следующую функцию:


    Выполнить функцию можно так:


    И вы можете проверить, встраивается ли она, таким образом:


    Этот запрос для нашей новой функции возвращает 1.

    Встраиваемая или нет, вы не увидите каких либо изменений в этом простом примере - я просто хотел указать на это как на более ценную возможность в будущем. Подробнее о встраиваемых функциях смотрите в публикации Brent Ozar’а.

    Наконец, давайте взглянем на немного туповатый трюк, который в целом полезен для определения того, наколько длинной может быть заковыченная строка. Меня интересует, какого максимального размера может быть вывод функции QUOTENAME. Если вы выполните следующий оператор:


    вернет []]]]], что на 2 символа больше, чем исходная строка. Если у нас 128 символов ], мы должны получить SELECT 127*2+4 или 258 символов, которые должен вывести следующий оператор.


    Мы могли бы это просто прочитать в документации о QUOTENAME, где говорится о результате nvarchar(258)! Следовательно, вот какого размера должна быть переменная/столбец, чтобы ее можно было обработать с помощью функции EscapeString:


    Здесь максимальная длина - это не 2 миллиарда как у varchar(max), а максимальная длина, которую может иметь ваш источник данных. Конечно, когда вы используете это значение со всеми экранированными строками, оно будет выглядеть больше, чем результирующее значение, но просто потому, что нам требуется пространство для 258 символов на имя, что не означает, что нам требуется именно 258 символов. Это просто еще одно препятствие, с которым вы столкнетесь, строя пуленепробиваемый генератор кода.

    SQL инъекции, подделка межсайтовых запросов, поврежденный XML… Страшные, страшные вещи, от которых мы все бы хотели защититься, да вот только знать бы почему это все происходит. Эта статья объясняет фундаментальное понятие, стоящее за всем этим: строки и обработка строк внутри строк.

    Основная проблема

    Это всего лишь текст. Да, просто текст — вот она основная проблема. Практически все в компьютерной системе представлено текстом (который, в свою очередь, представлен байтами). Разве что одни тексты предназначены для компьютера, а другие — для людей. Но и те, и те, всё же остаются текстом. Чтобы понять, о чем я говорю, приведу небольшой пример:

    Не поверите: это — текст. Некоторые люди называют его XML, но это — просто текст. Возможно, он не подойдет для показа учителю английского языка, но это — всё еще просто текст. Вы можете распечатать его на плакате и ходить с ним на митинги, вы можете написать его в письме своей маме… это — текст.

    Тем не менее, мы хотим, чтобы определенные части этого текста имели какое-то значение для нашего компьютера. Мы хотим, чтобы компьютер был в состоянии извлечь автора текста и сам текст отдельно, чтобы с ним можно было что-то сделать. Например, преобразовать вышеупомянутое в это:

    Откуда компьютер знает, как сделать это? Ну, потому что мы весьма кстати обернули определенные части текста специальными словами в забавных скобках, как, например, <author> и </author> . Поскольку мы сделали это, мы можем написать программу, которая искала бы эти определенные части, извлекала текст и использовала бы его для какого-нибудь нашего собственного изобретения.

    Иными словами, мы использовали определенные правила в нашем тексте, чтобы обозначить некое особое значение, которое кто-то, соблюдая те же правила, мог бы использовать.
    Ладно, это всё не так уж и трудно понять. А что если мы хотим использовать эти забавные скобки, имеющие какое-то особое значение, в нашем тексте, но без использования этого самого значения. Примерно так:

    Символы "<" и ">" не являются ничем особенным. Они могут законно использоваться где угодно, в любом тексте, как в примере выше. Но как же наша идея о специальных словах, типа <author> ? Значит ли это, что " < n and y > " тоже является каким-то ключевым словом? В XML — возможно да. А возможно нет. Это неоднозначно. Поскольку компьютеры не очень справляются с неоднозначностями, то что-то в итоге может дать непредвиденный результат, если мы не расставим сами все точки над i и не устраним неоднозначности.
    Решить эту дилемму можно, заменив неоднозначные символы чем-то однозначным.

    Теперь, текст должен стать полностью однозначным. "&lt;" равносильно "<", а "&gt;" — ">".
    Техническое определение этого — экранирование, мы избегаем специальные символы, когда не хотим, чтобы они имели свое особое значение.

    Если определенные символы или последовательности символов в тексте имеют особое значение, то должны быть правила, определяющие, как разрешить ситуации, когда эти символы должны использоваться без привлечения своего особого значения. Или, другими словами, экранирование отвечает на вопрос: «Если эти символы такие особенные, то как мне их использовать в своем тексте?».
    Как можно было заметить в примере выше, амперсанд (&) — это тоже специальный символ. Но что делать, если мы хотим написать "&lt;", но без интерпретации этого как "<"? В XML, escape-последовательность для &, это — " &amp; ", т.е. мы должны написать: " &amp;lt; "

    Другие примеры

    XML — не единственный случай «страдания» от специальных символов. Любой исходный код, в любом языке программирования может это продемонстрировать:

    Всё просто — обычный текст четко отделяется от «не текста» двойными кавычками. Таким же образом можно использовать и мой текст из курса математического анализа:

    Клево! И даже не нужно прибегать к экранированию! Но, подождите, а что, если я хочу процитировать кого-нибудь?

    Хм… печаль, тоска. Как человек, Вы можете определить где начинается и заканчивается текст и где находится цитата. Однако это снова стало неоднозначным для любого компьютера. Мы должны придумать какие-то правила экранирования, которые помогали бы нам различить буквальный " и ", который означает конец текста. Большинство языков программирование используют косую черту:

    "\" делает символ после него не специальным. Но это, опять-таки, значит, что "\" — специальный символ. Для однозначного написания этого символа в тексте, к нему нужно добавить такой же символ, написав: "\\". Забавно, не так ли?

    Атака!

    Другой распространенный пример и источник многих проблем безопасности — SQL запросы. SQL — язык, предназначенный для упрощения общения с базами данных:

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

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

    Для того, чтобы сделать это полезным, подобные запросы не хард-кодятся, а строятся на основе пользовательского ввода. Это же предложение, направленное на использование разными пользователями:

    В случае, если Вы просто просматриваете эту статью: Это — анти-пример! Это худшее, что Вы когда-либо могли сделать! Это кошмар безопасности! Каждый раз, когда Вы будете писать что-то подобное, будет погибать один невинный котенок! Ктулху сожрет Вашу душу за это!

    А теперь давайте посмотрим, что здесь происходит. $_POST['name'] — значение, которое некий случайный пользователь ввел в некую случайную форму на вашем случайно веб-сайте. Ваша программа построит SQL-запрос, использующий это значение в качестве имени пользователя, которого Вы хотели бы найти в БД. Затем это SQL «предложение» отправляется прямиком в БД.

    Вроде бы звучит все не так ужасно, да? Давайте попробуем ввести несколько случайных значений, которые можно ввести на вашем случайном веб-сайте и какие запросы из этого получатся:

    Joe'; DROP TABLE users; --

    Первый запрос выглядит не страшно, а вполне себе мило, правда? Номер 2, кажется, «несколько» повреждает наш синтаксис из-за неоднозначного '. Чертов немец! Номер 4 какой-то дурацкий. Кто бы такое написал? Это ведь не имеет смысла…
    Но не для БД, обрабатывающей запрос… БД понятия не имеет от куда этот запрос поступил, и что он должен значить. Единственное, что она видит — это два запроса: найти номер пользователя по имени Joe, а затем удалить таблицу users (что сопровождается комментарием '), и это будет успешно сделано.

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

    Впереееееед!

    Следующий шаг: XSS атаки. Действуют они аналогично, только применяются к HTML.
    Допустим, Вы решили проблемы с БД, получаете данные от пользователя, записываете в базу и выводите их назад на веб-сайт, для доступа пользователям. Это то, что делает типичный форум, система комментариев и т.д. Где-то на вашем сайте есть что-то подобное:

    Хм… Опять эти осквернители наших скобок. Ну, с технической точки зрения они могут быть неоднозначными, но браузер простит нам это, правда?

    Не следует понимать буквально

    В вышеупомянутых случаях, мы хотим каким-то образом сообщить нашей БД или браузеру, что это просто текст, ты с ним ничего не делай! Другими словами, мы хотим «удалить» особые значения всех специальных символов и ключевых слов из любой информации, предоставленной пользователем, ибо мы ему не доверяем. Что же делать?

    Что? Что говоришь, мальчишка? Ах, ты говоришь, «экранирование»? И ты абсолютно прав, возьми печеньку!
    Если мы применим экранирование к пользовательским данным до объединения их с запросом, то проблема решена. Для наших запросов к БД это будет что-то вроде:

    Просто одна строка кода, но теперь больше никто не может «взломать» нашу базу данных. Давайте снова посмотрим как будут выглядеть SQL-запросы, в зависимости от ввода пользователя:
    Alex

    Joe'; DROP TABLE users; --

    mysql_real_escape_string без разбора помещает косую черту перед всем, у чего может быть какое-то особое значение.

    Далее, заменим наш скрипт на форуме:

    Обратите внимание, что значения, полученные от пользователи, на самом деле не «повреждены». Любой браузер парсит этот как HTML и выведет на экран все в правильной форме.

    Что возвращает нас к.

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

    Для полноты картины

    • Validation
      Вы можете проверить, соответствует ли пользовательский ввод некоторой заданной спецификации. Если Вы требуете ввода числа, а пользователь вводит нечто другое, программа должна сообщить ему об этом и отменить ввод. Если все это правильно организовать, то нет никакого риска схватить «DROP TABLE users» там, где, предполагалось, пользователь введет «42». Это не очень практично, для избегания HTML/SQL-инъекций, т.к. часто требуется принять текст свободного формата, который может содержать «подковырки». Обычно валидацию используют в дополнение к другим мерам.
    • Sanitization
      Вы можете так же «втихую» удалить любые символы, которые считаете опасными. Например, просто удалить что-либо похожее на HTML-тег, что избежать добавления на ваш форум. Проблема в том, что вы можете удалить вполне законные части текста.
      Prepared SQL statements
      Есть специальные функции, делающие то, чего мы и добивались: заставляют БД понять различия между самим SQL-запросом и информацией, предоставленной пользователями. В РНР они выглядят примерно так:

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

    Экранирование кавычек в php, javascript и sql

    Что такое экранирование кавычек

    Чтобы дать определение этому понятию, для начала приведу небольшой пример объявления строки.

    Практически в любом языке программирования мы используем следующий принцип объявления строковой переменной:

    var text = "Название моего блога компании - lifeexample " ;

    Если нам нужно передать в строковую переменную текст содержащий кавычки и мы попытаемся сделать это таким образом:

    то произойдет ошибка, поскольку вместо одной строки интерпретатор увидит две:

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

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

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

    Php экранирование кавычек

    В php экранировать кавычки можно несколькими способами, первый из них аналогичен рассматриваемому выше.

    Например, мы имеем строку с авторской и прямой речью, которая содержит кавычки:

    "Как же вы поживаете?" – спросила Екатерина Ивановна. "Ничего, живем понемножечку", – ответил Старцев (Чехов)

    Чтобы вывести ее на страницу, в PHP следует делать одним из следующих способов.

    Экранирование обратным слешем:

    echo " \" Как же вы поживаете? \" – спросила Екатерина Ивановна. \" Ничего, живем понемножечку \" , – ответил Старцев (Чехов)" ;

    Экранирование одинарными кавычками

    echo '"Как же вы поживаете?" – спросила Екатерина Ивановна. "Ничего, живем понемножечку", – ответил Старцев (Чехов)' ;

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

    Зачем может понадобиться экранирование кавычек в PHP

    Помимо разобранного примера с выводом строк, экранирование кавычек и других спец символов зачастую необходимо при работе с БД.

    Чтобы не допустить, различного рода проблем при работе с базой данных, перед сохранением данных в таблицы можно использовать функцию addslashes

    Обе эти функции являются стандартными в php и экранируют спецсимволы строк. Когда и какую использовать, зависит от конкретных задач. Например addslashes лучше использовать для сериализованной строки при записи ее в базу, а mysql_real_escape_string для всех пользовательских данных пришедших с формы на сайте.

    Зачастую магические кавычки включены по умолчанию на сервере, это можно узнать из информацией полученной при выполнении функции

    javascript экранирование кавычек

    Очень часто, особенно в javascript приходится работать со строками, содержащими HTML разметку.

    В javascript экранирование кавычек происходит аналогичным образом, либо обратным слешем, либо использованием разного типа кавычек.
    Пример с обратным слешем:

    var html = "<div >\" example \" style= \" color:green \" >Блок с зеленым текстом</div>" ;

    Пример с внутренними кавычками:

    var html = '<div style="color:green">Блок с зеленым текстом</div>' ;

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

    var html = '<div style="color:green"> \
    Блок с зеленым текстом \
    </div>' ;

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

    Довольно редко, но можно столкнуться с задачей передать HTML разметку в сериализованной строке формата JSON. Если строка содержит символы переноса, то формат JSON будет нарушен.

    Чтобы избежать этих проблем нужно прогнать текст с переносом строк через функцию JSON.stringify()

    JSON.stringify() – доступна только после подключения библиотеки jquery.

    Sql экранирование кавычек

    Для экранирования кавычки в sql нужно их дублировать.

    Убрать экранирование кавычек

    Убрать экранирование кавычек в php можно стандартной функцией stripslashes();

    В javascript не существует аналога stripslashes, но ведь мы всегда можем воспользоваться регулярным выражением, которое поможет нам убрать экранирование кавычек в javascript

    В данной статье я постарался раскрыть тему экранирования кавычек в php, js, mysql и показать в каких случаях необходимо применять экранирование. Надеюсь, статья оказалась полезной. Подписывайтесь на рассылку, ставьте лайки, добавляйтесь в друзья 😉




    Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.

    Читайте также: