Перейти к содержимому
Назад к пути
Теория 2 мин чтения

4. Фундаментальная защита: Prepared Statements

Prepared Statements: Серебряная пуля

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

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


1. Как это работает: Разделение КОДА и ДАННЫХ

В уязвимом коде вы смешиваете команду (SELECT) и данные (id=123) в одну строку в самом Go. База данных получает эту строку и пытается её РАСПОЗНАТЬ (PARSING).

В Prepared Statements сценарий меняется:

  1. PREPARE: Go говорит базе: "Вот мой шаблон запроса: SELECT * FROM users WHERE id = ?. Подготовься к нему!" (База парсит шаблон БЕЗ данных).
  2. BIND: Go говорит базе: "А вот данные для этого шаблона: 123. Просто подставь их в готовый шаблон и не пытайся их выполнять как код!".
  3. EXECUTE: База выполняет уже готовый запрос с подставленными данными.

2. Почему это на 100% безопасно?

Даже если хакер подставит в ? вредоносный код типа 1' OR '1'='1, для базы данных это будет просто ДЛИННАЯ СТРОКА ТЕКСТА. Она никогда не попадет в этап парсинга (Parsing stage). База будет искать пользователя с ТАКИМ странным именем 1' OR '1'='1. Соответственно, хакер ничего не добьется.


Таблица работы: Sprintf vs Prepared

Параметр Использование Sprintf Использование Prepared
Процесс Парсим всю строку целиком Парсим шаблон, BINDим данные
Безопасность 🔴 УЯЗВИМО 🟢 АБСОЛЮТНО БЕЗОПАСНО
Скорость 🌕 Обычная 🌕 Высокая (шаблон повторен)
Вердикт Смерть через взлом ЗОЛОТОЙ СТАНДАРТ

3. Как это выглядит в Go (библиотека database/sql)

// ✅ ПРАВИЛЬНЫЙ Go-код (Prepared Statements)
query := "SELECT id FROM users WHERE username = ? AND password = ?"
err := db.QueryRow(query, username, password).Scan(&userID)

В этом примере Go-пакет database/sql сам берет на себя всю работу по отправке шаблона и данных в базу раздельно.


4. Сравнение подходов: stdlib vs библиотека

Критерий Fix A: database/sql (stdlib) Fix B: sqlx / squirrel / GORM
Зависимости Нет — только стандартная библиотека Внешний пакет (go get ...)
Параметризация Ручная (? / $1) Автоматическая (fluent API или struct mapping)
Преимущество Минимум зависимостей, полный контроль Читаемость, защита от ошибок при сложных запросах
Риск Легко забыть ? в одном месте Raw-запросы внутри ORM остаются уязвимыми

Разделение контекста — это закон. Когда данные не могут стать кодом, хакер теряет свою силу.

Теперь посмотрим, как реализовать этот принцип в Go, используя стандартную библиотеку database/sql.

Продолжить чтение

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

Когда закончишь — отметь раздел, чтобы продолжить.

🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru