Secure code review: ручное ревью кода и поиск уязвимостей в веб-приложении

Secure code review — это чтение исходного кода с одним вопросом: что здесь может сделать пользователь, которому этого не положено. Мы идём от рисков, а не от первого файла: права на сервере, вход и сессии, запросы к базе, файлы, секреты, зависимости. На выходе список находок, где у каждой есть место в коде, сценарий, серьёзность и готовая правка, а не выгрузка сканера на сотни строк. Это ревью кода и конфигурации, а не атака на боевую систему и не аттестация.

Аудит кода на уязвимости — от 200 000 ₽, 2–3 недели на одно приложениеУ каждой находки место в коде, сценарий и правкаЧитаем в вашем репозитории, боевую систему не трогаем

С чем приходят

Когда нужен человек с кодом перед глазами, а не только сканер

Скоро релиз, а безопасность никто не смотрел

Код писали под срок, ревью в команде проверяло, работает ли функция, а не что она позволяет. Нужен взгляд со стороны и список, который можно закрыть до релиза.

Сканер выдал длинный список, и непонятно, что важно

Автоматический анализ находит шаблонные замечания и пропускает логику доступа. Нужен тот, кто отделит замечание, до которого можно добраться из интернета, от замечания в мёртвом коде.

Код достался от другого подрядчика

Секреты могли остаться в истории репозитория, права могли быть реализованы только в интерфейсе. Читать лучше до того, как на систему придут новые клиенты.

Клиент просит подтверждение

Опросник спрашивает про хранение паролей, проверку прав, обновление библиотек. Ответы без чтения кода пересказывают слова разработчиков. Отчёт ревью заменяет пересказ.

Что читаем

Семь участков кода, где живут уязвимости

Список участков подгоняем под ваш стек. В разрезе категорий OWASP те же места описаны на странице аудита безопасности.

Участок кода
Что ищем
Типичный признак в коде
Что получаете
Участок кодаТочки входамаршруты и обработчики
Что ищемВсе места, куда попадает запрос извне
Типичный признак в кодеМаршрут добавлен без общей проверки пользователя; служебный адрес остался от отладки
Что получаетеПеречень точек входа с отметкой о проверке входа и прав
Участок кодаПроверка правдоступ к объектам
Что ищемЧто проверяется: роль, принадлежность организации, действие
Типичный признак в кодеОбъект берётся по номеру из запроса, владелец не сверяется
Что получаетеОбработчики без проверки владельца и сценарий, как открыть чужое
Участок кодаВход и сессииаутентификация
Что ищемХранение паролей, срок токенов, восстановление доступа
Типичный признак в кодеБыстрый хеш без соли, токен без срока, сессия живёт после смены пароля
Что получаетеЗамечания с готовыми правками
Участок кодаБаза и выводзапросы и страницы
Что ищемКак ввод пользователя попадает в запрос и в страницу
Типичный признак в кодеЗапрос собирается склейкой строк, экранирование отключено, ответ отдаёт объект целиком
Что получаетеМеста внедрения и шаблон безопасной замены для вашего стека
Участок кодаФайлы и обращения вовнезагрузка и ссылки
Что ищемТипы файлов, пути, адреса, которые сервер запрашивает по просьбе пользователя
Типичный признак в кодеИмя файла от пользователя попадает в путь; сервер ходит по любой ссылке из формы
Что получаетеФункции с обращением вовне и нужные ограничения
Участок кодаСекреты и шифрованиеключи и токены
Что ищемГде лежат ключи, чем шифруются данные, откуда случайные значения
Типичный признак в кодеКлюч в истории коммитов, самодельное шифрование, предсказуемые токены восстановления
Что получаетеСписок секретов к замене и порядок замены
Участок кодаЖурнал, зависимости, сборкаследы и пакеты
Что ищемЧто пишется в журнал, откуда берутся пакеты, кто меняет сборку
Типичный признак в кодеПароли в журнале, версии не зафиксированы, секреты сборки доступны всем
Что получаетеЧто убрать, что добавить и как обновлять
Метод

Как мы читаем код, чтобы отчёту можно было верить

Сначала карта, потом чтение

Первые дни уходят на то, чтобы понять, что в приложении ценно: деньги, персональные данные, документы, административные действия. С вашим разработчиком помечаем участки, где ошибка стоит дороже всего, и читаем с них.

От ввода к опасному месту

Основной приём: берём данные, пришедшие снаружи, и идём по коду до места, где они что-то делают: попадают в запрос, в путь к файлу, в страницу, в решение о доступе. Если по дороге данные проверены, дальше не идём. Если нет, строим сценарий и воспроизводим его на тестовом стенде или локальной копии. Находка без воспроизведения помечается как «вероятная», и в отчёте это видно.

Программа и человек

Анализаторы кода, проверка зависимостей и поиск секретов запускаются в первые дни: они дёшевы и находят шаблонные ошибки. Каждое срабатывание читает человек: часть окажется ложной, часть относится к коду, который не выполняется. Серьёзность определяется после чтения, а не по метке сканера. Часть замечаний снимает короткий ответ разработчика на вопрос «зачем здесь так»: тогда это пояснение, и оно попадает в отчёт.

Чтение и сканер

Что находит человек, а что программа

Класс проблемы
Пример
Почему программа не справляется
Что делаем при чтении
Класс проблемыДоступ к чужим объектамсканер почти не находит
ПримерКлиент меняет номер документа в адресе и получает чужой
Почему программа не справляетсяАнализатор не знает, кто должен видеть заказ
Что делаем при чтенииСверяем обработчики с матрицей «роль — объект — действие», пробуем чужие номера
Класс проблемыЛогика сценариевсканер не находит
ПримерСкидка применяется дважды, платёж повторяется
Почему программа не справляетсяНужно знать, как должно быть, а в коде этого нет
Что делаем при чтенииРазбираем сценарии вместе с вашим аналитиком
Класс проблемыГонки и повторысканер не находит
ПримерДва одновременных запроса списывают остаток дважды
Почему программа не справляетсяНужно знать, где проверка и запись разнесены
Что делаем при чтенииЧитаем такие места и воспроизводим на стенде
Класс проблемыСекреты и библиотекисканер находит хорошо
ПримерКлюч в истории репозитория, известная дыра в зависимости
Почему программа не справляетсяНе отличает рабочий ключ от тестового и не видит, вызывается ли уязвимая функция
Что делаем при чтенииОцениваем достижимость и расставляем приоритет
Как выглядит находка

Из чего состоит одно замечание в отчёте

  • Место. Файл, функция, строка на конкретной ревизии репозитория: через месяц код изменится, а замечание должно остаться понятным.
  • Сценарий. Что делает пользователь и что получает; для воспроизведённых находок приложены шаги.
  • Серьёзность. По двум вопросам: насколько легко добраться и что будет потеряно.
  • Правка. Не «исправьте проверку прав», а способ для вашего стека с примером изменения.
  • Как убедиться, что закрыто. Тест или шаги, которые разработчик повторит после правки. Без них находка вернётся при следующем релизе.

Условный пример. В обработчике скачивания счёта документ берётся по номеру из адреса, принадлежность организации не проверяется. Сценарий: клиент меняет номер на соседний и получает чужой счёт. Серьёзность высокая. Правка: добавить условие по организации в выборку и вернуть одинаковый отказ на чужой и на несуществующий номер. Проверка: тест, где клиент А запрашивает документ клиента Б и ожидает отказ.

Приоритеты

Как расставляем серьёзность

Уровень
Пример
Что получает нарушитель
Предлагаемый порядок
УровеньКритическийдобраться может любой посетитель
ПримерВнедрение запроса в публичной форме
Что получает нарушительДанные или права без входа в систему
Предлагаемый порядокЗакрыть до релиза или отключить функцию
УровеньВысокийнужен вход, но чужие данные доступны
ПримерОткрытие чужих документов по номеру
Что получает нарушительДанные других клиентов
Предлагаемый порядокЗакрыть до релиза, добавить тест
УровеньСреднийнужны особые условия
ПримерНет ограничения попыток входа
Что получает нарушительВозможность подбора, заметная в журнале
Предлагаемый порядокЗакрыть в ближайших релизах
УровеньНизкийтрудно использовать
ПримерПодробные тексты ошибок
Что получает нарушительСведения для подготовки нападения
Предлагаемый порядокВключить в плановые работы
Постоянное ревью

Разовое чтение или проверка в каждом релизе

Разовое ревью отвечает на вопрос «что сейчас». Через несколько релизов ответ устаревает: добавился обработчик, кто-то поправил проверку «временно». Поэтому ревью встраивают в процесс команды, и брать эти уровни можно по очереди:

  • Чек-лист к запросу на слияние. Пять-семь вопросов под ваш стек и ваши роли: проверены ли права, не попадает ли ввод в запрос, нет ли секретов в коде.
  • Обязательный проверяющий для чувствительных мест. Изменения в коде входа, прав, платежей и загрузки файлов не сливаются без отдельного согласующего. В GitLab и GitHub для этого есть файл владельцев кода.
  • Автоматические проверки в сборке. Анализатор кода, проверка зависимостей и поиск секретов на каждое изменение. Правила подбираем под проект, чтобы ложные срабатывания не приучили команду нажимать «пропустить».

Перед крупным релизом мы читаем изменённые рискованные участки и отвечаем письменно. Это входит в сопровождение пакетами часов.

Граница

Ревью кода, аудит безопасности, пентест: где проходит граница

Ревью кода на уязвимости отвечает на вопрос «что не так в коде»: читаем исходники и конфигурацию, воспроизводим находки на вашем стенде, объясняем, как исправить.

Аудит безопасности веб-приложения шире: все категории OWASP Top 10, проверки на стенде, разбор окружения. Для одного сервиса и вопроса про код хватит ревью, для подтверждения клиентам по всему приложению берите аудит. Аудит кода и архитектуры отвечает на другой вопрос: можно ли систему развивать и сопровождать.

Пентест — попытка взлома боевой системы по согласованным правилам. Мы его не проводим, аттестацию не проводим, лицензии ФСТЭК у нас нет. Если нужно именно это, нужна другая организация, и мы скажем об этом на первом созвоне.

Вход сотрудников и единый вход разобраны на странице SSO и MFA, защита программного интерфейса от перебора и обхода прав — в статье «Как защитить API от взлома».

Что делаем

Из чего состоит работа и сколько она стоит

Цены совпадают с тарифами: ревью идёт по шкале обследования, цена называется до начала работ. Остановиться можно после отчёта.

Ревью одного приложения

Карта точек входа и ролей, автоматические проверки, чтение рискованных участков, воспроизведение на вашем стенде, отчёт и созвон с разработчиками.

200 000 ₽ · 2–3 недели

Ревью нескольких приложений

Плюс границы между сервисами, ключи и токены обмена, общие библиотеки и конвейер сборки.

350 000 ₽ · 3–4 недели

Ревью крупного контура

Много систем и команд, закрытая среда. Сводный отчёт и план исправлений по очереди.

500 000 ₽ · 4–6 недель

Исправление найденного

Правки и тесты по отчёту, если хотите поручить их нам. Оценка по каждой находке, этап с приёмкой.

после ревью · от 150 000 ₽

Настройка проверок в сборке

Анализатор кода, проверка зависимостей, поиск секретов и чек-лист для запросов на слияние под ваш стек.

150 000–400 000 ₽ · 2–8 недель

Сопровождение

Ревью изменений перед релизами, разбор срабатываний, обновление зависимостей. Сверх пакета — 5 000 ₽ в час.

20 000 / 60 000 / 120 000 ₽ в месяц
Процесс

Как идёт ревью

До начала — Рамки и доступы

Какие репозитории и ветки, где стенд. Доступ к коду на чтение, данные на стенде обезличены, соглашение о неразглашении при необходимости.

Дни 1–3 — Карта и первые проверки

Точки входа, роли, ценные данные. Автоматические проверки и разбор срабатываний. Согласуем, какие участки читаем первыми.

Недели 1–2 — Чтение

От ввода к опасным местам, воспроизведение на стенде, вопросы разработчикам. Критические находки сообщаем сразу, не дожидаясь отчёта.

Конец срока — Отчёт

Находки с местом, сценарием, серьёзностью, правкой и способом проверки. Отдельно список того, что мы не читали, и причины.

После — Разбор и повторная проверка

Проходим по отчёту с вашими разработчиками. После исправлений по желанию проверяем, что находки закрыты и новых нет.

Цена

Что двигает цену ревью внутри ступени

Размер кода и разнообразие технологий

Небольшой сервис на одном языке читается быстрее, чем система, где рядом лежат серверная часть, интерфейс, скрипты обмена и устаревший модуль.

Число ролей и точек входа

Работа растёт по числу правил доступа, а не экранов. Пять ролей с правами на уровне договоров и полей требуют иного объёма, чем две роли.

Доступность людей и стенда

Если разработчики отвечают в тот же день, срок ровный. Если авторов кода уже нет, читаем дольше и чаще пишем «вероятно».

Закрытая среда

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

Контроль

Что остаётся у вас и чего мы не делаем

Остаётся у вас

  • Отчёт целиком и материалы воспроизведения: шаги, тестовые данные, скрипты.
  • Тесты на права и безопасность, которые мы написали, остаются в вашем репозитории.
  • Исходный код ваш с первого коммита. Мы работаем в вашем репозитории или на копии, которую удаляем по акту.
  • Право остановиться после любой ступени: сделанное остаётся у вас по акту.

Мы этого не делаем

  • Не атакуем боевые системы и не проводим пентест по сценариям внешнего нарушителя.
  • Не проводим аттестацию и не даём заключений о соответствии требованиям регуляторов. Лицензии ФСТЭК у нас нет.
  • Не подключаем WAF, SIEM или системы обнаружения вторжений как услугу и не защищаем от DDoS.
  • Не читаем код мобильных приложений и встроенных программ устройств.
  • Не обещаем, что уязвимостей не осталось: отчёт описывает прочитанное. Юридические вопросы по персональным данным решает ваш юрист.
  • Не дежурим круглосуточно и не берём работы дешевле 150 000 ₽.
Инструменты

Чем читаем и проверяем

Языки, которые читаем
  • Python: Django, FastAPI
  • JavaScript и TypeScript: Node.js, React, Vue
  • PHP: Laravel, Symfony
  • Go; другие языки оговариваем до договора
Что запускаем помимо чтения
  • Semgrep и аналоги для поиска шаблонных ошибок
  • Проверка зависимостей: менеджер пакетов и OWASP Dependency-Check
  • gitleaks или аналог для поиска секретов в истории
  • Docker для воспроизведения находок на изолированной копии
Материалы

Материалы по теме

Статья

Как защитить API от взлома: вход, лимиты, перебор

Порядок защиты программного интерфейса: что проверять в коде, какие лимиты вводить и как не пропустить чужие данные.

  • Вход и права
  • Лимиты
  • Перебор
Читать →
Статья

OWASP Top 10 простыми словами для заказчика

Десять классов ошибок без жаргона и пять проверок, которые заказчик сделает сам.

  • Десять категорий
  • Проверки самому
  • Как читать отчёт
Читать →
Статья

Мультиарендность в SaaS: как разделить данные клиентов

Три схемы изоляции и тесты, которые показывают, что клиент А не видит клиента Б.

  • Три схемы
  • Политики
  • Тесты изоляции
Читать →
Заявка

Расскажите, какой код нужно прочитать

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

Спасибо, заявка отправлена. Ответим в течение рабочего дня.

Не удалось отправить. Напишите в телеграм или позвоните.

Вопросы

Частые вопросы: secure code review

Сколько стоит secure code review?

Ревью одного приложения — 200 000 ₽ и 2–3 недели, нескольких приложений — 350 000 ₽ и 3–4 недели, крупного контура — 500 000 ₽ и 4–6 недель. Цена называется до начала работ, остановиться можно после отчёта. Исправление найденного оценивается отдельно по каждой находке, от 150 000 ₽ за этап.

Чем ревью кода отличается от аудита безопасности?

Ревью читает исходный код глубже и ведёт диалог с разработчиками. Аудит идёт по всем категориям OWASP Top 10, включает проверки на стенде и разбор окружения. Для одного сервиса и вопроса про код хватает ревью, для подтверждения клиентам по всему приложению нужен аудит.

Какие языки вы читаете?

Уверенно читаем Python, JavaScript и TypeScript, PHP и Go. Другие языки возможны, но решаем это до договора: если проверяющий не пишет на языке, ревью превращается в просмотр без понимания. Код приложений под iOS и Android не читаем.

Нужно ли отдавать вам исходный код?

Нужен доступ на чтение в вашем репозитории или копия на выделенной машине в вашем контуре. Данные на стенде обезличиваются, после работ доступ закрывается, копия удаляется по акту. Соглашение о неразглашении подписываем до начала.

Вы гарантируете, что уязвимостей не останется?

Нет. Отчёт описывает прочитанное и проверенное, и в нём есть список того, что мы не читали. Ревью снижает вероятность типовых и дорогих ошибок и показывает слабые места, но полностью безопасных приложений не бывает.

Можно ли проверять каждый релиз, а не один раз?

Можно. Мы настраиваем автоматические проверки в сборке и чек-лист для запросов на слияние, а перед крупными релизами читаем изменённые рискованные участки. Сопровождение стоит 20 000, 60 000 или 120 000 ₽ в месяц, часы сверх пакета — 5 000 ₽ в час.

Это пентест?

Нет. Мы не атакуем боевую систему и не имитируем внешнего нарушителя: читаем код и конфигурацию, воспроизводим находки на вашем стенде или локальной копии. Лицензии ФСТЭК и права проводить аттестацию у нас нет.

Вы работаете только в Ростове-на-Дону?

Мы в Ростове-на-Дону, работаем с заказчиками по всей России: удалённо и в вашем контуре. Доступ к системам и обследование согласуем на старте с вашей службой безопасности.