Как экранировать символы в SQL ‘[

Как экранировать символы в SQL: кавычки, обратные слеши и безопасные строки

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

Что такое экранирование символов и зачем оно нужно

Экранирование — это способ обозначить, что специальный символ должен восприниматься как обычный текст. В SQL специальными считаются символы, которые используются как разделители строк (' и "), спецсимволы в операторе LIKE (% и _), а также обратная косая черта (\) в некоторых диалектах. Неправильное экранирование или двойное экранирование может привести к логическим ошибкам в запросах, а использование строк из непроверённых источников создаёт риск SQL‑инъекций. Документация и опыт разработчиков подчёркивают, что некорректное вложенное экранирование приводит к уязвимостям, и для работы с непроверенными данными следует использовать подготовленные выражения, чтобы исключить возможность SQL‑инъекции.

Как экранировать одинарные кавычки

В большинстве диалектов SQL строки заключаются в одинарные кавычки. Чтобы вставить апостроф внутри строки, его нужно удвоить. Такой подход называется doubling up и описан в справочниках по языкам программирования: язык SQL, как и Pascal, BASIC и Fortran, избегает конфликтов разделителей, удваивая кавычку внутри строкового литерала. Например:

-- Правильный способ экранирования апострофа
SELECT 'O''Brien' AS LastName;

-- Строка с кавычками внутри
SELECT 'Это не "ошибка", это строка';
  • O''Brien — корректная запись фамилии O’Brien.
  • Вторая строка показывает, что двойные кавычки внутри одинарных кавычек не требуют экранирования.

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

-- SQL Server
SELECT REPLACE(@input, '''', '''''');

Экранирование обратной косой черты и других специальных символов

Диалекты SQL по‑разному трактуют обратную косую черту (\).

  • MySQL в режиме, когда параметр NO_BACKSLASH_ESCAPES выключен (режим по умолчанию в старых версиях), использует \ для экранирования специальных символов: \' для апострофа, \" для кавычки, \\ для самой косой черты. В современных версиях рекомендуется включать NO_BACKSLASH_ESCAPES и использовать стандартное удваивание кавычек.
  • PostgreSQL поддерживает стандартное экранирование апострофа через двойные кавычки. Для обратной косой черты используется синтаксис E'string' с escape‑последовательностями: E'c:\\temp' создаст путь c:\temp.
  • SQL Server не поддерживает обратную косую черту как символ экранирования для строк. Вместо этого используются функции QUOTENAME и REPLACE.

Пример для MySQL:

-- Экспорт данных с экранированием обратной косой черты
INSERT INTO files(path) VALUES('C:\\Data\\backup.sql');

Пример для PostgreSQL:

-- Использование escape‑литерала
INSERT INTO files(path) VALUES (E'C:\\Data\\backup.sql');

Спецсимволы в операторе LIKE

Операторы LIKE и ILIKE используют % (любой набор символов) и _ (один символ). Чтобы искать эти символы как текст, используйте слово ESCAPE и задайте символ экранирования:

-- Найти строки, содержащие символ подчёркивания
SELECT name
FROM users
WHERE name LIKE '%\_%' ESCAPE '\\';

-- Найти строки, содержащие процент
SELECT comment
FROM logs
WHERE comment LIKE '%\%%' ESCAPE '\\';

Здесь обратная косая черта перед % и _ указывает, что символ должен интерпретироваться буквально. Значение после ESCAPE определяет символ, которым мы экранируем шаблон.

Безопасные динамические запросы и защита от SQL‑инъекций

Экранирование символов важно, но для данных от пользователя этого недостаточно. Опыт показывает, что использование строк как кода может привести к уязвимостям, особенно в веб‑приложениях, и злоумышленники могут выполнить SQL‑инъекцию через недостатки экранирования. Лучший способ защититься — использовать подготовленные выражения (prepared statements) и привязку параметров. Суть подхода в том, что структура запроса компилируется отдельно, а значения подставляются как параметры, поэтому они не могут изменить логику SQL.

Пример на T‑SQL (SQL Server):

-- Использование параметров в хранимой процедуре
CREATE PROCEDURE dbo.GetUser
 @UserName NVARCHAR(100)
AS
BEGIN
 SET NOCOUNT ON;
 SELECT * FROM dbo.Users WHERE UserName = @UserName;
END

Пример на C# с ADO.NET:

string query = "SELECT * FROM Users WHERE UserName = @name";
using (var cmd = new SqlCommand(query, connection))
{
 cmd.Parameters.AddWithValue("@name", userInput);
 using (var reader = cmd.ExecuteReader())
 {
 while (reader.Read())
 {
 // обработка результата
 }
 }
}

Благодаря параметрам апострофы и другие специальные символы воспринимаются как данные, и риск SQL‑инъекции исчезает.

Экранирование идентификаторов: QUOTENAME и квадратные скобки

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

-- Добавить квадратные скобки вокруг имени
SELECT QUOTENAME('My Database'); -- [My Database]

-- Использовать кавычки
SELECT QUOTENAME('Table Name', '"'); -- "Table Name"

Также имена можно заключать в квадратные скобки вручную: [My Table]. В стандарте SQL используются двойные кавычки: "Table". Для динамического SQL лучше всегда использовать QUOTENAME.

Таблица: способы экранирования в разных СУБД

СУБДКак экранировать апострофДругие особенности
SQL ServerУдвоить ' → ''Функция QUOTENAME для идентификаторов; параметризованные запросы.
MySQL'O''Brien' либо \' (если не включён NO_BACKSLASH_ESCAPES)Спецсимволы \n, \r, \0; рекомендуется удваивать кавычки и использовать подготовленные запросы.
PostgreSQL'O''Brien'Возможен синтаксис E'' для escape‑последовательностей; standard_conforming_strings должен быть включён.
SQLite'It''s OK'Обратная косая черта не имеет специального значения, поэтому для спецсимволов достаточно удвоить кавычку.

Полезные функции для экранирования

  • REPLACE(строка, что, на_что) — заменяет одну подстроку другой, удобно для удвоения кавычек.
  • QUOTENAME(имя [, разделитель]) (SQL Server) — добавляет разделители вокруг идентификатора и экранирует внутренние закрывающие символы.
  • STRING_ESCAPE(строка, тип) (SQL Server 2016+) — экранирует спецсимволы для JSON, XML и HTML.
  • ESCAPE символ — используется в LIKE для указания символа экранирования.

Лучшие практики и рекомендации

  1. Используйте параметры вместо конкатенации. Экранируйте строковые литералы лишь для фиксированного SQL; для данных от пользователя используйте подготовленные выражения. Несоблюдение этого правила приводит к SQL‑инъекциям.
  2. Чётко определяйте диалект SQL. Разные СУБД по‑разному трактуют обратную косую черту и escape‑последовательности. Читайте документацию для вашей СУБД.
  3. Удваивайте кавычки. Самый универсальный способ экранирования апострофа — писать две одинарные кавычки подряд.
  4. Используйте специальные функции. В SQL Server есть QUOTENAME, а в MySQL — QUOTE() для безопасного формирования литералов.
  5. Документируйте код. Явно комментируйте места, где происходит экранирование, чтобы другим разработчикам было понятно, зачем это сделано.

Внутренние ссылки

Итоги

Корректное экранирование символов в SQL — важная часть работы разработчика. Апострофы экранируются путём удвоения, спецсимволы в шаблонах LIKE прячутся через ESCAPE, а обратная косая черта имеет особое значение только в некоторых диалектах. Однако простого экранирования недостаточно — для работы с пользовательскими данными используйте подготовленные выражения и привязку параметров, чтобы защитить систему от SQL‑инъекций. Зная эти правила и применяя их на практике, вы избежите ошибок в запросах и повысите безопасность ваших приложений.

+ There are no comments

Add yours