← Блог

Безопасная разработка ПО: как защита закладывается с первого дня

Безопасность нельзя купить отдельной услугой в конце проекта. Когда система уже написана, любая защита превращается в заплатки: дорогие, неполные и ломающие то, что работало. Поэтому я закладываю безопасность в процесс с первого дня: в требования, архитектуру, код, проверки и развёртывание. Ниже — как это выглядит на практике. Это часть общего подхода, описанного в статье Разработка ПО с нуля под ключ: от идеи до релиза.

Принцип: безопасность — свойство системы

Показательный пример — CRM Keel: как спроектировать систему, в которой нельзя подсмотреть. Требование «менеджер не должен знать декларанта» можно реализовать, скрыв поле в интерфейсе, и можно — разнеся данные по раздельным базам так, чтобы сервер физически не мог их выдать. Первый вариант ломается одним запросом к API. Второй вариант защищён самой структурой системы. Я всегда выбираю второй путь, если цена ошибки высока.

1. Моделирование угроз на этапе проектирования

Ещё до написания кода я отвечаю на вопросы:

  • Что мы защищаем? Персональные данные, коммерческие тайны, управляющие команды, доступность сервиса.
  • От кого? Внешний злоумышленник, недобросовестный сотрудник, ошибка пользователя, скомпрометированная зависимость.
  • Как могут атаковать? Для оценки использую классификацию STRIDE: подмена личности, изменение данных, отказ от действий, раскрытие информации, отказ в обслуживании, повышение привилегий.
  • Что делать? Для каждой угрозы определяю меру: запретить, ограничить, обнаружить или принять риск осознанно.

Результат — короткий документ, который становится частью Архитектура ПО: проектирование и планирование до первой строки кода. Он нужен, чтобы защита строилась по плану, а не по ощущению.

2. Безопасная архитектура

Из модели угроз вытекают архитектурные решения:

ПринципЧто это значит
Минимальные привилегииКаждый сервис и пользователь получает только те права, которые нужны для работы
Разделение данныхЧувствительное хранится отдельно и доступно узкому кругу
Защита в глубинуНесколько независимых барьеров: сбой одного не отдаёт систему целиком
Отказ по умолчаниюЕсли правило доступа не описано, доступ закрыт
Минимум внешних зависимостейМеньше чужого кода и внешних каналов, меньше поверхность атаки

Крайний случай — «Русло»: как строится IIoT-платформа для закрытой сети предприятия: платформа разворачивается внутри закрытой сети предприятия, без облачных зависимостей и доступа в интернет во время работы. Нет внешнего канала — нет и атак через него.

3. Безопасный код

На уровне кода я придерживаюсь практик, которые закрывают большинство распространённых уязвимостей из списка OWASP Top 10:

  • Проверка входных данных на границе системы. Данные пользователя, внешнего сервиса или устройства считаются недоверенными, пока не проверены.
  • Параметризованные запросы к базе. Никакой склейки SQL из строк: это закрывает инъекции. В Rust библиотека sqlx дополнительно проверяет запросы на этапе сборки.
  • Контроль доступа на сервере при каждом запросе, а не только в интерфейсе.
  • Безопасная работа с паролями и сессиями: стойкое хеширование, ограниченное время жизни, защита от перебора.
  • Аккуратные сообщения об ошибках: пользователь видит понятный текст, а подробности попадают в журнал.
  • Безопасность памяти. Для критичных систем я выбираю Rust, где целые классы ошибок (переполнение буфера, использование освобождённой памяти) отсекаются компилятором.

4. Секреты и конфигурация

Пароли, ключи и токены не хранятся в коде и репозитории. Они передаются через окружение или хранилище секретов, разные для разных сред. Доступ ограничен и журналируется. Если секрет всё же попал в репозиторий, он считается скомпрометированным и заменяется.

5. Зависимости и цепочка поставки

Современное приложение на 90 % состоит из чужого кода, поэтому его нужно контролировать:

  • минимизирую число зависимостей и выбираю зрелые, поддерживаемые;
  • фиксирую версии (lock-файлы), чтобы сборка была воспроизводимой;
  • регулярно проверяю зависимости на известные уязвимости штатными инструментами экосистемы (cargo audit, npm audit);
  • обновляю зависимости планово, а не только когда что-то сломалось.

6. Проверки в процессе

Безопасность проверяется на каждом этапе, а не перед релизом:

  1. Код-ревью с отдельным вниманием к правам доступа и обработке входных данных.
  2. Автоматические проверки в CI: линтеры, статический анализ, проверка зависимостей.
  3. Тесты на безопасность: попытки обращения к чужим данным, неверные права, граничные значения.
  4. Нагрузочные испытания, показывающие, как система ведёт себя под давлением. Для этого я использую в том числе собственный стенд «Исток».

Подробнее о проверках — в статьях Качество кода: что оно значит для бизнеса и как его обеспечить и Тестирование и приёмка ПО: как убедиться, что система работает до релиза.

7. Журналы, резервные копии и восстановление

Если что-то случилось, нужно уметь восстановить картину. Поэтому в системе есть журнал значимых действий (без паролей и лишних персональных данных), резервные копии и проверенная процедура восстановления. Резервная копия, которую никогда не пробовали восстановить, — это надежда, а не защита.

8. Персональные данные и правовая сторона

Работая с персональными данными, нужно понимать не только технику, но и закон: какие данные собирать, как долго хранить, кто имеет к ним доступ. Моё юридическое образование (степень магистра права) помогает обсуждать эти вопросы с заказчиком на одном языке и закладывать требования в архитектуру, а не вспоминать о них при проверке. При этом я не заменяю юриста вашей компании: итоговую оценку соответствия требованиям делают специалисты по вашему направлению.

Короткий чек-лист для заказчика

Вопросы, которые стоит задать любому подрядчику:

  • Есть ли у вас модель угроз для моей системы?
  • Где хранятся секреты и кто имеет к ним доступ?
  • Как вы контролируете зависимости?
  • Как проверяется контроль доступа?
  • Как проходит восстановление из резервной копии?
  • Что записано в журнал, а что нет?

Если на эти вопросы нет внятных ответов, безопасность, скорее всего, остаётся пожеланием.

Хотите, чтобы безопасность была встроена в ваш проект?

Напишите мне: Telegram @w1shmaster. Обсудим, что именно нужно защитить и как заложить это в систему с самого начала.

← Все посты