Статьи
17 декабря 2025 г.

Правила код-ревью по безопасности для команд разработки: чек-листы по языкам и типовым ошибкам
Код-ревью (от англ. code review – обзор кода) – это процесс проверки исходного кода программного обеспечения другими разработчиками (не автором) с целью поиска ошибок, приведения кода к единым стандартам и обмена опытом. Хотя код-ревью обычно считают средством улучшения стиля и качества кода, сегодня это один из мощнейших способов предотвращения угроз. Системный анализ безопасности на этапе проверки позволяет устранить большинство критических уязвимостей еще до того, как код попадет в рабочую среду.
Почему обычного код-ревью недостаточно?
Во многих командах ревью ограничивается проверкой логики, читаемости и производительности. Безопасность при этом рассматривается либо фрагментарно, либо полностью перекладывается на автоматические сканеры. Такой подход приводит к типовым проблемам:
уязвимости бизнес-логики не обнаруживаются SAST-инструментами;
небезопасные паттерны использования сторонних библиотек проходят ревью как «рабочие»;
ошибки конфигурации и обработки данных остаются незамеченными.
Эффективное код-ревью по безопасности требует формализованных правил и чек-листов, адаптированных под конкретный язык и стек технологий.
Универсальный чек-лист безопасности
Независимо от языка разработки, при ревью кода следует проверять:
Работу с входными/выходными данными:
происходит ли приведение данных к безопасному, единому формату (нормализация) с последующей валидацией;
используются ли «белые списки» (allow-list) вместо «черных списков» (black-list);
отсутствует ли слепое доверие данным клиента;
безопасна ли десериализация структурированных данных (JSON/XML/YAML) на предмет выполнения кода на сервере;
применяются ли prepared statements и плейсхолдеры для предотвращения SQL-инъекций при работе с БД;
происходит ли экранирование данных перед их выводом в интерфейс пользователя с целью предотвращения XSS.
>> Любые данные, приходящие извне, по умолчанию считаются опасными и ненадежными.
Аутентификацию и авторизацию:
проверяются ли права доступа на стороне сервера при каждом запросе, независимо от логики интерфейса;
исключается ли доверие к ролям и правам, передаваемым в параметрах или флагах со стороны клиента;
четко ли разграничены процессы идентификации, аутентификации и авторизации;
ограничивается ли срок жизни сессий и токенов и защищены ли они от подделки и кражи из браузера;
блокируются ли попытки массового перебора паролей и выдает ли система единую ошибку при неудачном входе;
происходит ли полная и немедленная инвалидация серверной сессии при выходе пользователя.
>> Никогда не верь клиенту в вопросах доступа: личность должна быть подтверждена, а каждое действие – санкционировано сервером.
Обработку ошибок и логирование:
не раскрываются ли детали реализации (стек-трейсы, версии библиотек, структура БД) в сообщениях об ошибках;
исключается ли попадание в логи секретов и конфиденциальных данных (паролей, токенов, ключей и ПДн);
используется ли централизованная обработка исключений для обеспечения единообразия ответов и предотвращения необработанных сбоев;
соблюдается ли достаточный уровень логирования событий безопасности (входы, отказы в доступе, изменение прав);
проводится ли очистка (маскирование) данных в логах при необходимости зафиксировать сам факт передачи объекта, содержащего чувствительную информацию.
>> Пиши в логи только то, что поможет восстановить ход событий, не раскрывая секретов и деталей защиты.
Работу с секретами:
отсутствуют ли в исходном коде любые жестко заданные (hardcoded) пароли, API-ключи, токены или сертификаты;
загружаются ли секреты из специализированных хранилищ (vault) или защищенных переменных окружения;
удалены ли из истории репозитория любые «временные» секреты, тестовые учетные данные и отладочные ключи доступа;
используются ли файлы-игнорирования (например, .gitignore), чтобы исключить случайное попадание локальных файлов с секретами в общую ветку;
предусмотрена ли возможность оперативной замены секретов без необходимости внесения изменений в сам программный код.
>> Пиши код так, будто завтра он окажется в открытом доступе, и в нем не останется ни одного ключа от целевой системы.
Типовые ошибки по языкам и платформам
Java / Kotlin
использование небезопасных десериализаторов (ObjectInputStream, старые версии Jackson/Fastjson);
игнорирование проверки цепочки сертификатов и использование самоподписанных TLS-сертификатов;
сборка запросов через конкатенацию строк;
использование предсказуемых генераторов случайных чисел (java.util.Random) в криптографии.
C / C++
выход за границы буфера (buffer overflow) при работе с массивами;
использование небезопасных функций без контроля длины: strcpy(), sprintf(), gets();
отсутствие проверок возвращаемых значений системных вызовов и функций выделения памяти;
использование после освобождения (use-after-free) и двойное освобождение памяти;
целочисленное переполнение (integer overflow), приводящее к некорректному выделению буфера.
Python
использование eval(), exec() и ast.literal_eval() для обработки данных пользователя;
небезопасная загрузка сериализованных объектов через pickle, marshal или shelve;
формирование команд shell через f-строки или конкатенацию (с использованием os.system, subprocess);
отключение проверки TLS-сертификатов «для удобства» в библиотеках типа requests;
выход за пределы директории (path traversal) при открытии файлов через open() без валидации пути.
JavaScript / TypeScript
прямая вставка данных в DOM через innerHTML или dangerouslySetInnerHTML;
отсутствие проверки схем JSON-ответов и входных данных в runtime;
хранение секретов и JWT-токенов в localStorage;
неправильная настройка CORS (Access-Control-Allow-Origin: * для приватных API).
Go
игнорирование возвращаемых ошибок (if err != nil);
утечки горутин (goroutine) из-за отсутствия контекста (context.Context) или таймаутов;
доступ к общим ресурсам без использования мьютексов;
чрезмерное использование пакета unsafe;
использование io.ReadAll() на внешних потоках данных без ограничения размера.
Что сделать для внедрения код-ревью безопасности?
Введите минимальный чек-лист, обязательный для каждого ревью.
Назначьте Security Champion’а в команде, отвечающего за качество ревью в разрезе безопасности.
Интегрируйте SAST и SCA для автоматизации и возможности сконцентрироваться на логике и угрозах.
Используйте каждую выявленную проблему как повод для актуализации внутреннего чек-листа и проведения командного разбора.
Чисто там, где не сорят
Безопасность кода – не скучный надзор «безопасников», а общее дело всей команды. Когда правила проверки понятны, а под рукой есть удобный чек-лист, поиск уязвимостей превращается из рутины в полезную привычку. Чем раньше мы заметим «слабое звено», тем меньше правок придется вносить в последний момент. В конечном итоге, качественный и защищенный код – это прежде всего наш спокойный сон и доверие пользователей.
Развивайтесь, и пусть ваши билды всегда выдают exit code 0!
Автор: Лариса Карпан, старший специалист по безопасной разработке Angara Security.
Автор: Angara Security Группа компаний Angara, представленная системным интегратором Angara Technologies Group и сервис-провайдером Angara Professional Assistance, оказывает полный спектр услуг по информационной безопасности: поставку оборудования и ПО, проектирование, внедрение, сопровождение ИТ- и ИБ-систем клиентов, а также предлагает востребованные сервисы по обеспечению информационной безопасности по модели подписки.