Ответ
Защита от SQL-инъекций строится на одном фундаментальном принципе: никогда не доверять пользовательскому вводу и не вставлять его напрямую в SQL-запрос.
Основной метод: Параметризованные запросы (Prepared Statements) Это самый надежный способ. СУБД четко разделяет код запроса и данные.
// УЯЗВИМЫЙ КОД (НИКОГДА ТАК НЕ ДЕЛАЙТЕ)
string userInput = Request.Form["username"];
string query = $"SELECT * FROM Users WHERE Name = '{userInput}'";
// Если userInput = "admin' OR '1'='1", запрос сломает логику.
// ЗАЩИЩЕННЫЙ КОД с параметрами
string safeQuery = "SELECT * FROM Users WHERE Name = @UserName";
using (SqlCommand command = new SqlCommand(safeQuery, connection))
{
// Параметр @UserName будет обработан как ДАННЫЕ, а не как часть кода SQL.
command.Parameters.AddWithValue("@UserName", userInput);
// ... выполнение команды
}
Дополнительные и сопутствующие меры:
- ORM (Entity Framework, Dapper): Современные ORM по умолчанию используют параметризацию.
// Entity Framework Core - инъекция невозможна var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Name == userInput); - Принцип наименьших привилегий: У учетной записи приложения в БД должны быть минимально необходимые права (обычно только SELECT, INSERT, UPDATE, DELETE для конкретных таблиц, но не DROP, TRUNCATE и т.д.).
- Валидация и санитизация ввода: Отклоняйте входные данные, не соответствующие ожидаемому формату (например, в поле "телефон" должны быть только цифры). Это не заменяет параметризацию, но является хорошей практикой.
- Хранимые процедуры: Эффективны только если вы передаете параметры в них, а не конкатенируете строки внутри самой процедуры.
Итог: Всегда используйте параметризованные запросы или ORM. Экранирование символов — ненадежный и устаревший метод.
Ответ 18+ 🔞
Давай я тебе на пальцах объясню, как этих уёбков, которые пытаются через форму логина твою базу данных выцедить, нахуй посылать. Всё строится на одном простом, как три рубля, правиле: пользовательскому вводу — нихуя не верим. Вообще. Ни на йоту.
Спасительный круг: Параметризованные запросы (Prepared Statements) Это твой бронежилет, нательный крест и каска в одном флаконе. База данных тогда чётко понимает, где инструкция, а где просто данные, которые нужно тупо подставить.
// КОД-САМОУБИЙЦА (ДЕЛАЕШЬ ТАК — ЗАКРОЙ ЛАВОЧКУ)
string userInput = Request.Form["username"]; // Допустим, сюда введут ' OR '1'='1
string query = $"SELECT * FROM Users WHERE Name = '{userInput}'";
// Запрос превратится в: SELECT * FROM Users WHERE Name = '' OR '1'='1'
// И тебе пиздец, потому что войдёт кто угодно.
// КОД-МУЖИК (ДЕЛАЙ ТОЛЬКО ТАК)
string safeQuery = "SELECT * FROM Users WHERE Name = @UserName";
using (SqlCommand command = new SqlCommand(safeQuery, connection))
{
// Смотри, магия: @UserName — это просто метка. База НЕ видит тут команды.
command.Parameters.AddWithValue("@UserName", userInput);
// ... и выполняй команду спокойно
}
Вот и вся магия. База данных получает команду и данные отдельно, и уже сама, безопасно, их соединяет. Инъекция тупо не проходит.
Что ещё можно сделать, чтобы спать спокойнее:
- ORM (Entity Framework, Dapper): Это вообще красота. Они под капотом сами всё параметризуют, тебе даже думать не надо.
// Entity Framework Core — тут нихуя не внедришь var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Name == userInput); - Принцип "ты мне не начальник": У аккаунта, от имени которого твое приложение лезет в базу, должны быть урезанные права. Пусть только выбирает и меняет данные в нужных таблицах, а не хуячит базу направо и налево. Не давай ему права на DROP или EXECUTE каких-то левых процедур.
- Проверка на вшивость: Если у тебя поле "возраст", отфильтруй нахуй всё, кроме цифр. Это не защита от инъекций, это просто здравый смысл, чтобы мусор не тащить. Но заменять этим параметризацию — идиотизм.
- Хранимые процедуры: Они могут быть полезны, но только если ты не начинаешь внутри них склеивать строки вручную, как последний ламер. Иначе это просто перенос проблемы на другой уровень.
Короче, резюме простое, как мычание: Забей на все эти ручные экранирования кавычек — это каменный век. Втыкай параметризованные запросы или используй нормальный ORM, и спи, блядь, спокойно.