Безопасная разработка ПО: как защита закладывается с первого дня
Безопасность нельзя купить отдельной услугой в конце проекта. Когда система уже написана, любая защита превращается в заплатки: дорогие, неполные и ломающие то, что работало. Поэтому я закладываю безопасность в процесс с первого дня: в требования, архитектуру, код, проверки и развёртывание. Ниже — как это выглядит на практике. Это часть общего подхода, описанного в статье Разработка ПО с нуля под ключ: от идеи до релиза.
Принцип: безопасность — свойство системы
Показательный пример — CRM Keel: как спроектировать систему, в которой нельзя подсмотреть. Требование «менеджер не должен знать декларанта» можно реализовать, скрыв поле в интерфейсе, и можно — разнеся данные по раздельным базам так, чтобы сервер физически не мог их выдать. Первый вариант ломается одним запросом к API. Второй вариант защищён самой структурой системы. Я всегда выбираю второй путь, если цена ошибки высока.
1. Моделирование угроз на этапе проектирования
Ещё до написания кода я отвечаю на вопросы:
- Что мы защищаем? Персональные данные, коммерческие тайны, управляющие команды, доступность сервиса.
- От кого? Внешний злоумышленник, недобросовестный сотрудник, ошибка пользователя, скомпрометированная зависимость.
- Как могут атаковать? Для оценки использую классификацию STRIDE: подмена личности, изменение данных, отказ от действий, раскрытие информации, отказ в обслуживании, повышение привилегий.
- Что делать? Для каждой угрозы определяю меру: запретить, ограничить, обнаружить или принять риск осознанно.
Результат — короткий документ, который становится частью Архитектура ПО: проектирование и планирование до первой строки кода. Он нужен, чтобы защита строилась по плану, а не по ощущению.
2. Безопасная архитектура
Из модели угроз вытекают архитектурные решения:
| Принцип | Что это значит |
|---|---|
| Минимальные привилегии | Каждый сервис и пользователь получает только те права, которые нужны для работы |
| Разделение данных | Чувствительное хранится отдельно и доступно узкому кругу |
| Защита в глубину | Несколько независимых барьеров: сбой одного не отдаёт систему целиком |
| Отказ по умолчанию | Если правило доступа не описано, доступ закрыт |
| Минимум внешних зависимостей | Меньше чужого кода и внешних каналов, меньше поверхность атаки |
Крайний случай — «Русло»: как строится IIoT-платформа для закрытой сети предприятия: платформа разворачивается внутри закрытой сети предприятия, без облачных зависимостей и доступа в интернет во время работы. Нет внешнего канала — нет и атак через него.
3. Безопасный код
На уровне кода я придерживаюсь практик, которые закрывают большинство распространённых уязвимостей из списка OWASP Top 10:
- Проверка входных данных на границе системы. Данные пользователя, внешнего сервиса или устройства считаются недоверенными, пока не проверены.
- Параметризованные запросы к базе. Никакой склейки SQL из строк: это закрывает инъекции. В Rust библиотека sqlx дополнительно проверяет запросы на этапе сборки.
- Контроль доступа на сервере при каждом запросе, а не только в интерфейсе.
- Безопасная работа с паролями и сессиями: стойкое хеширование, ограниченное время жизни, защита от перебора.
- Аккуратные сообщения об ошибках: пользователь видит понятный текст, а подробности попадают в журнал.
- Безопасность памяти. Для критичных систем я выбираю Rust, где целые классы ошибок (переполнение буфера, использование освобождённой памяти) отсекаются компилятором.
4. Секреты и конфигурация
Пароли, ключи и токены не хранятся в коде и репозитории. Они передаются через окружение или хранилище секретов, разные для разных сред. Доступ ограничен и журналируется. Если секрет всё же попал в репозиторий, он считается скомпрометированным и заменяется.
5. Зависимости и цепочка поставки
Современное приложение на 90 % состоит из чужого кода, поэтому его нужно контролировать:
- минимизирую число зависимостей и выбираю зрелые, поддерживаемые;
- фиксирую версии (lock-файлы), чтобы сборка была воспроизводимой;
- регулярно проверяю зависимости на известные уязвимости штатными инструментами экосистемы (
cargo audit,npm audit); - обновляю зависимости планово, а не только когда что-то сломалось.
6. Проверки в процессе
Безопасность проверяется на каждом этапе, а не перед релизом:
- Код-ревью с отдельным вниманием к правам доступа и обработке входных данных.
- Автоматические проверки в CI: линтеры, статический анализ, проверка зависимостей.
- Тесты на безопасность: попытки обращения к чужим данным, неверные права, граничные значения.
- Нагрузочные испытания, показывающие, как система ведёт себя под давлением. Для этого я использую в том числе собственный стенд «Исток».
Подробнее о проверках — в статьях Качество кода: что оно значит для бизнеса и как его обеспечить и Тестирование и приёмка ПО: как убедиться, что система работает до релиза.
7. Журналы, резервные копии и восстановление
Если что-то случилось, нужно уметь восстановить картину. Поэтому в системе есть журнал значимых действий (без паролей и лишних персональных данных), резервные копии и проверенная процедура восстановления. Резервная копия, которую никогда не пробовали восстановить, — это надежда, а не защита.
8. Персональные данные и правовая сторона
Работая с персональными данными, нужно понимать не только технику, но и закон: какие данные собирать, как долго хранить, кто имеет к ним доступ. Моё юридическое образование (степень магистра права) помогает обсуждать эти вопросы с заказчиком на одном языке и закладывать требования в архитектуру, а не вспоминать о них при проверке. При этом я не заменяю юриста вашей компании: итоговую оценку соответствия требованиям делают специалисты по вашему направлению.
Короткий чек-лист для заказчика
Вопросы, которые стоит задать любому подрядчику:
- Есть ли у вас модель угроз для моей системы?
- Где хранятся секреты и кто имеет к ним доступ?
- Как вы контролируете зависимости?
- Как проверяется контроль доступа?
- Как проходит восстановление из резервной копии?
- Что записано в журнал, а что нет?
Если на эти вопросы нет внятных ответов, безопасность, скорее всего, остаётся пожеланием.
Хотите, чтобы безопасность была встроена в ваш проект?
Напишите мне: Telegram @w1shmaster. Обсудим, что именно нужно защитить и как заложить это в систему с самого начала.