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

4. Hardening: принцип наименьших привилегий

Hardening: Принцип наименьших привилегий

Даже если в Go-коде допущена досадная ошибка, масштаб ущерба можно существенно минимизировать правильной настройкой базы данных. Принцип «наименьших привилегий» (Least Privilege) гласит: каждый процесс должен иметь ровно столько прав, сколько ему необходимо для выполнения его задач, и ни капли больше.

Этот принцип сформулирован Джеромом Зальцером и Майклом Шредером ещё в 1975 году в их работе «The Protection of Information in Computer Systems», и за полвека он не утратил актуальности. В контексте веб-приложений Least Privilege означает: бэкенд, обслуживающий формы регистрации и поиска товаров, не должен иметь права удалять таблицы или читать системные каталоги — даже если в коде есть SQL-инъекция. Атакующий, пробивший Go-приложение через fmt.Sprintf, упирается в стенку при попытке выполнить DROP TABLE или прочитать pg_user — потому что у database-пользователя, под которым работает Go-приложение, просто нет таких прав.

Аналогия из физического мира: представь банк, где у каждого сотрудника есть карточка-пропуск с разными уровнями доступа. Кассир может зайти только в зону обслуживания клиентов; менеджер — в офис и хранилище наличных дневного оборота; директор — везде, кроме главного хранилища, куда есть доступ только у двух человек. Если злоумышленник украл карточку кассира, он не сможет добраться до сейфов — пропускной режим не пустит. Так же и database-пользователь Go-приложения: даже после успешной инъекции его «карточка» открывает только ограниченный набор операций.

Разберемся, как изолировать ваше приложение так, чтобы даже успешная инъекция не позволила хакеру удалить таблицы.


1. Механика: "Изоляция одного пользователя"

Ошибка многих новичков — использовать для веб-приложения пользователя с правами суперадмина. В этом случае хакер через SQLi может сделать всё, вплоть до DROP TABLE. Типичный сценарий: разработчик создаёт базу через createdb mydb под своим суперпользователем, копирует строку подключения в .env файл — и эта строка с правами суперюзера улетает в production. Удобно для разработки, катастрофа для безопасности.

Как это должно быть реализовано:

  1. Создаем отдельного пользователя app_client.
  2. Даем ему права только на SELECT, UPDATE и INSERT для нужных таблиц.
  3. Полностью блокируем доступ к системным схемам, таким как information_schema или pg_catalog.

2. Коды настройки (СУБД PostgreSQL/MySQL)

Сейчас увидим разницу между удобной (но опасной) и безопасной конфигурацией прав. Это первая строка обороны на уровне инфраструктуры — её настраивает DBA или DevOps-инженер при создании окружения, и для команды разработки это становится «прозрачным» защитным слоем: код продолжает работать как раньше, но при инциденте ущерб ограничен.

-- ❌ СМЕРТЕЛЬНО ОПАСНО: Дать все права приложению
GRANT ALL PRIVILEGES ON DATABASE secure_code_db TO app_user;

-- ✅ БЕЗОПАСНЫЙ ПОДХОД: Минимум прав
-- Читать только таблицу продуктов
GRANT SELECT ON products TO app_user;
-- Писать только в таблицу логов
GRANT INSERT ON web_logs TO app_user;
-- Запретить доступ к системным данным
REVOKE ALL ON SCHEMA information_schema FROM app_user;

3. Таблица "Ущерб" при разных правах в БД

Привилегии в БД Что сможет хакер через SQLi?
Superuser 🔴 УДАЛИТЬ всё, вытащить пароли, RCE
Owner 🔴 Вытащить все данные, изменить их
Least Priv. 🟢 Только поиск товаров (что и делает сайт)

4. Почему это критично для Go?

Даже идеальный Go-код может столкнуться с уязвимостью в сторонней библиотеке или редким «краевым случаем». Ограничение прав в базе — это ваш ПОСЛЕДНИЙ РУБЕЖ ЗАЩИТЫ (Defense in Depth). В реальной практике Defense in Depth — это многослойная архитектура: WAF на edge, валидация параметров на уровне Go-middleware, параметризованные запросы в SQL, ограниченные права у БД-пользователя, network policy запрещающая egress из БД-pod в интернет, мониторинг аномалий в SIEM. Каждый слой может быть пробит, но злоумышленнику нужно пробить ВСЕ для успешной атаки.

В Go вы просто указываете данные этого ограниченного пользователя в строке подключения:

// Логин app_client имеет минимум прав в базе
db, err := sql.Open("postgres", "postgres://app_client:pass@localhost/db")

Best practice: для микросервисной архитектуры создаётся отдельный database-пользователь под каждый сервис, и каждый из них имеет узкий набор прав только под свою предметную область. Сервис каталога — только SELECT на products, categories; сервис заказов — SELECT/INSERT/UPDATE на orders, order_items; сервис аналитики — только SELECT на read-replica с заранее настроенными агрегациями. Это паттерн «database per service» от Сэма Ньюмена, описанный в книге «Building Microservices». В Kubernetes секреты-credentials хранятся в HashiCorp Vault или Sealed Secrets, никогда в открытом виде в репозитории.

Дополнительная защита: PostgreSQL row-level security (RLS) добавляет фильтр прямо на уровне СУБД — например, «пользователь app_user видит только строки, где tenant_id = current_setting('app.tenant_id')». Даже если в Go-коде забыли добавить WHERE tenant_id = ?, RLS не пустит запрос за пределы tenant'а. Это особенно важно для multi-tenant SaaS-приложений, где утечка данных между клиентами означает потерю compliance-сертификации.


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

Соответствие стандартам: PCI-DSS требование 7 — «Restrict access to cardholder data by business need to know» прямо обязывает применять least privilege для всех систем, работающих с карточными данными. ISO 27001 Annex A.9.4.1 «Information access restriction». NIST SP 800-53 AC-6 «Least Privilege» — фундаментальное требование для всех федеральных систем США. GDPR Article 32 — «adequate technical measures» — регулятор смотрит, ограничены ли права у database-юзера приложения, если хочет понять, насколько серьёзны меры защиты данных.

Мы завершили блок разведки и hardening'а. После квиза нас ждет погружение в одну из самых коварных тем — слепые инъекции.

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

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

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

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