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

5. Объединение значений (CONCAT)

Объединение значений (CONCAT): Склеивание ответов

Иногда в оригинальном запросе доступна всего одна текстовая колонка, а хакеру нужно вытащить сразу несколько полей — например, логин и пароль. Для этого используются функции конкатенации, которые позволяют "сжать" несколько данных в одну строку.

С точки зрения Go-разработчика паттерн знакомый — на бэкенде вы регулярно делаете fmt.Sprintf("%s:%s", login, pass) для формирования basic-auth токена. Атакующий проделывает ровно то же самое, но не на стороне приложения, а на стороне базы данных. Если ваш SELECT возвращает на фронт только одну колонку (например, name в JSON-ответе /api/products), атакующий «упаковывает» в эту единственную колонку весь интересующий его секрет — два, три, десять полей через разделитель.

Изучим синтаксис объединения в разных СУБД и поймем, почему разделители вроде двоеточия являются верным признаком атаки. Аналогия — посылка с двойным дном: на этикетке (структура JSON) написано «один документ», а внутри упаковано пять документов, склеенных скотчем, потому что курьер досматривает только размер посылки, не содержимое.


1. Механика: "Склеивание полей"

Представьте запрос в Go-коде: SELECT id, name, price FROM products WHERE category = '%s' (через fmt.Sprintf).

Это стандартный паттерн интернет-магазина: страница /category/electronics рендерит список товаров через html/template, и каждый item-card показывает только name как текст, id уходит в data-id атрибут, price — в <span> форматирования. UI-разработчик не задумывается, что атакующий может через UNION SELECT подменить значение колонки name в трёх запросах подряд.

Хакер знает, что ему доступна только ОДНА текстовая колонка (name). Но он хочет вытащить сразу username и password из таблицы users. Решение — упаковать оба поля в одно: username || ':' || password в PostgreSQL даёт строку вида admin:5f4dcc3b5aa765d61d8327deb882cf99. Эта строка попадает в колонку name UNION-результата, и фронтенд аккуратно отрендерит её как название «товара» рядом с настоящими товарами магазина.

Разница в синтаксисе СУБД:

  • PostgreSQL / SQLite: username || ':' || password
  • MySQL: CONCAT(username, ':', password)

2. Финальный удар хакера в Go

Хакер вводит в category: ' UNION SELECT 1, username || ':' || password, 3.14 FROM users--

Что произойдет в Go-хендлере:

// ❌ Go просто склеивает...
query := fmt.Sprintf("... UNION SELECT 1, username || ':' || password, 3.14 FROM users--'")
// ...и выводит строки в цикле на страницу

ИТОГ: Вместо названия "iPhone", на сайте появится строка: admin:mySuperSecretPassword123. Если пароли хранятся как bcrypt-хэши ($2a$10$...), атакующий получит хэши — а дальше offline brute force через hashcat на нескольких GPU. Yahoo Voices 2012: 450 тысяч паролей утекли именно так, через UNION с CONCAT — атакующие потом восстановили большинство по словарю.


3. Таблица работы: Исходный SQL vs CONCAT Атака

Параметр Исходный SQL Результат атаки (SQL Injection)
Тип name CONCAT(username, ':', password)
Количество 1 поле 2 поля в одном!
Статус 🟢 БЕЗОПАСНО 🔴 ВЗЛОМАНО

4. Почему хакеры любят разделители? (Двоеточие)

Хакер добавляет : или другой редкий символ, чтобы потом в своем скрипте (или в браузере) легко разделить логин и пароль. Это "отпечаток" хакера, по которому вы легко можете опознать попытку взлома. Для SIEM/SOC это важный сигнал: если в access-логе nginx или в логах вашего Go-приложения мелькает строка вида ':admin:hash:role:, или сам пользовательский ввод содержит ||, CONCAT(, 0x3a (hex для :) — это почти всегда автоматизированный sqlmap-like инструмент.

Защита всё та же — параметризация. С db.Query("SELECT id, name, price FROM products WHERE category=?", category) ввод хакера ' UNION SELECT 1, username || ':' || password, 3.14 FROM users-- идёт в базу как литерал, и PostgreSQL/MySQL вернёт пустой результат — нет ни одного товара с таким category-именем. Никакого UNION в плане выполнения не появляется.


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

Теперь, когда мы изучили все методы нападения, пришло время поговорить о защите. Сравним использование «сырых» запросов с популярными Go-библиотеками и ORM.

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

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

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

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