Ответ
Основной и самый надежный метод защиты — использование параметризованных запросов (prepared statements). Этот подход разделяет сам SQL-запрос (код) и данные, передаваемые пользователем, не позволяя данным интерпретироваться как исполняемый код.
Принцип работы
- Шаблон запроса: Сначала в базу данных отправляется шаблон SQL-запроса с плейсхолдерами (
?или%s) вместо пользовательских данных. - Передача данных: Отдельно от шаблона передаются данные для подстановки в плейсхолдеры. Драйвер базы данных безопасно вставляет их, экранируя все спецсимволы.
Пример на Python (DB-API)
import sqlite3
user_input = "' OR 1=1; --"
# ❌ НЕПРАВИЛЬНО (уязвимо):
# Строка просто конкатенируется, что позволяет выполнить инъекцию.
query_vulnerable = f"SELECT * FROM users WHERE login = '{user_input}'"
# ✅ ПРАВИЛЬНО (безопасно):
# Данные передаются вторым аргументом в виде кортежа.
query_safe = "SELECT * FROM users WHERE login = ?"
cursor.execute(query_safe, (user_input,))
Дополнительные уровни защиты:
- Использование ORM (Object-Relational Mapping), таких как SQLAlchemy или Django ORM. Они по умолчанию создают параметризованные запросы.
# SQLAlchemy автоматически создает безопасный запрос user = session.query(User).filter(User.login == user_input).first() - Валидация и санация ввода: Проверяйте, что вводимые данные соответствуют ожидаемому формату (например, число является числом).
- Минимальные привилегии для пользователя БД: Учетная запись, используемая приложением, должна иметь доступ только к необходимым ей таблицам и операциям.
Ответ 18+ 🔞
А, слушай, вот эта вся хрень с SQL-инъекциями — это вообще классика жанра, пиздец. Представь, какой-то умник думает: "А дай-ка я склею строчку запроса из того, что пользователь ввёл". И понеслась, блядь. Это как дать незнакомцу ключи от своей квартиры и сказать: "Только в шкаф не лезь".
Так вот, самый надёжный способ не облажаться — это параметризованные запросы, они же prepared statements. Суть проще пареной репы: ты пишешь запрос, а вместо данных оставляешь дырки, знаки вопроса. А потом отдельно, как будто в пробирку, подсовываешь туда пользовательский ввод. База данных сама всё грамотно экранирует, и никакая инъекция не пролезет. Это как кормить с ложечки — безопасно и под контролем.
Как это работает, на пальцах
- Шаблон: Сначала ты кидаешь в базу шаблон: "Эй, найди мне всех пользователей, где логин равен вот этой штуке". А вместо самой штуки — вопросик.
- Данные: Потом, отдельным заходом, говоришь: "А штука вот эта —
' OR 1=1; --". И база, вместо того чтобы это исполнить, тупо воспринимает это как строку текста, со всеми кавычками и минусами. Всё, пиздец инъекции.
Смотри, как это выглядит в коде (Python)
import sqlite3
# Допустим, злодей ввёл вот такую хуйню
user_input = "' OR 1=1; --"
# ❌ КАК ДЕЛАТЬ НЕ НАДО, ЕБАНУТЬСЯ МОЖНО!
# Слепил строку — и в топку. Это прямой путь на стендап про айтишников.
query_vulnerable = f"SELECT * FROM users WHERE login = '{user_input}'"
# Получится: SELECT * FROM users WHERE login = '' OR 1=1; --'
# А 1=1 — это всегда правда, ёпта! Всех пользователей вытащит, пиздец.
# ✅ А ВОТ КАК НАДО, БЛЯДЬ!
# Запрос с дыркой, данные — отдельно. Красота.
query_safe = "SELECT * FROM users WHERE login = ?"
cursor.execute(query_safe, (user_input,))
# База сама разберётся, что это просто текст, а не команда. Спи спокойно.
Ещё круче — использовать ORM
ORM — это такая магия, которая сама за тебя эти безопасные запросы строит. Типа SQLAlchemy или Django ORM. Ты там просто пишешь на почти человеческом языке, что тебе нужно, а они под капотом уже всё правильно делают. Волшебство, ёпта!
# SQLAlchemy, например. Выглядит как обычный код, а под капотом — безопасный запрос.
user = session.query(User).filter(User.login == user_input).first()
# Никакого ручного склеивания, никакого геморроя. Иди пей чай.
Ну и, конечно, подстрахуйся
- Проверяй, что вводят: Если ждёшь номер телефона — убедись, что это цифры, а не скрипт на пайтоне, блядь. Валидация — твой друг.
- Не давай лишних прав: Учётка, от имени которой работает твоё приложение, должна иметь доступ только к тому, что ей реально нужно. Не к админке всей базы, а только к таблице
users, например. Принцип минимальной привилегии, ёбта. Если что-то пойдёт не так — ущерб будет ограничен.
Вот и вся наука. Не изобретай велосипед, не склеивай строки, и будет тебе счастье. А то потом будешь сидеть и думать: "И кто же это у меня в базе все пароли поудалял?.."