Исправить проверку доступа иногда можно за несколько строк. Но если через пропущенную проверку уже скачали клиентскую базу, нескольких строк хватит только для начала. Дальше придётся выяснять масштаб утечки, закрывать доступ злоумышленникам, проверять соседние сервисы, отвечать клиентам и разбираться с последствиями. Код почти тот же, задача уже совсем другая.
DevSecOps помогает уменьшить вероятность такого превращения. Подход объединяет разработку, безопасность и эксплуатацию в общий процесс, где опасные решения обсуждают до написания кода, типовые ошибки ищут автоматически, а за выпущенным приложением продолжают следить. Главный вопрос здесь вполне земной. Когда компания предпочитает обнаружить проблему, пока разработчик работает над функцией или когда функцию уже освоили посторонние?
Чем DevSecOps отличается от DevOps
DevOps сближает разработчиков и специалистов, которые запускают и поддерживают приложения. Команды автоматизируют сборку, тестирование и выпуск изменений, быстрее получают обратную связь и совместно отвечают за работу сервиса. Вместо передачи программы через организационную стену появляется непрерывный процесс от изменения кода до работающей версии.
Безопасность вполне может входить в зрелый DevOps. Неверно представлять подход как гонку за скоростью, где защиту намеренно забыли. Название DevSecOps делает обязанности по безопасности явными. Требования к доступу, проверка сторонних компонентов, защита системы сборки и работа с уязвимостями становятся частью повседневной инженерной работы.
При позднем подключении службы безопасности разработчики сначала принимают архитектурные решения и реализуют продукт, а затем приносят готовую систему на проверку. Даже хороший специалист оказывается в неудобном положении. До запуска осталось несколько дней, договоры подписаны, а исправление найденной ошибки требует переделать хранение данных. Вопрос «как правильно защитить» быстро уступает вопросу «можно ли пока согласовать».
| Что сравниваем | Безопасность проверяют в конце | DevSecOps |
|---|---|---|
| Требования к защите | Уточняют при проверке готового продукта | Обсуждают вместе с функциями и архитектурой |
| Обратная связь | Отчёт после большого объёма работы | Замечания к конкретному решению или изменению кода |
| Типовые проверки | Запускают перед выпуском или по отдельной заявке | Встраивают в сборку и тестирование |
| Ответственность | Служба безопасности должна найти и согласовать | Команда исправляет, специалисты по защите помогают оценить риск, руководство обеспечивает ресурсы |
| После выпуска | Проверку считают завершённой | Отслеживают новые уязвимости, атаки и изменения настроек |
Общая ответственность не означает, что каждый программист обязан стать специалистом по расследованию атак. Разработчикам нужны понятные правила, безопасные заготовки и доступная помощь. Службе безопасности нужны знания о продукте и возможность влиять на решения до того, как переделка станет дорогой.
Что означает «сдвиг влево»
На привычной схеме разработки требования располагают слева, затем идут проектирование, код, тестирование и выпуск. «Сдвиг влево», или shift left, переносит часть работы по безопасности ближе к началу. Проверять права доступа при обсуждении функции дешевле организационно, чем объяснять за день до запуска, почему клиентам нельзя показывать чужие документы.
Речь не только о более раннем запуске сканера. При сдвиге влево команда заранее определяет, какие данные защищает, кому доверяет и какие действия запрещает. Затем превращает требования в архитектурные ограничения, настройки и тесты. Чем конкретнее требование, тем проще проверить результат.
Например, фраза «личный кабинет должен быть безопасным» почти бесполезна. Требование «пользователь одной организации не может прочитать, скачать или изменить документы другой» уже задаёт проверяемое поведение. Разработчик понимает, где нужны ограничения, тестировщик получает сценарии, а специалист по безопасности может проверить обходные пути.
Переносить абсолютно все проверки к моменту написания кода невозможно. Некоторые ошибки проявляются только в собранном приложении, при взаимодействии сервисов или в реальных настройках инфраструктуры. Правильный принцип проще рекламного лозунга. Каждую проблему стоит искать на самом раннем этапе, где проверка способна дать осмысленный результат.
Правда ли позднее исправление стоит в сто раз дороже
Утверждение «после выпуска любая уязвимость обходится в сто раз дороже» звучит убедительно, но универсальным законом не является. Стоимость зависит от характера ошибки, устройства системы, качества тестов, способа выпуска обновлений и того, успел ли кто-нибудь воспользоваться уязвимостью. Замена версии библиотеки в одном сервисе и переделка общей модели доступа требуют разной работы.
В отчёте NIST 2002 года о последствиях недостаточного тестирования таблица 5-2 иллюстрирует рост стоимости исправления ошибки, внесённой при написании кода. Авторы прямо обозначили таблицу как пример, а не норматив. Относительные значения выглядят следующим образом.
| Когда нашли ошибку, внесённую при написании кода | Относительная стоимость в примере NIST |
|---|---|
| При написании кода и модульном тестировании | 1 |
| При интеграционном и системном тестировании | 10 |
| При бета-тестировании | 20 |
| После выпуска продукта | 30 |
Таблица относится к программным ошибкам в целом и описывает историческую модель. Применять множители к современному проекту без собственных измерений нельзя. Однако механизм понятен. Позднее исправление затрагивает больше уже выполненной работы, требует повторных проверок и доставки обновления пользователям.
Для безопасности нужно отдельно считать стоимость исправления и совокупные потери от инцидента. В первом случае компания платит за работу инженеров и выпуск обновления. Во втором добавляются расследование, восстановление, простой, помощь пострадавшим и возможные выплаты. Разрыв действительно может составлять порядки, но сравнение уже касается разных по объёму задач. Называть весь ущерб от утечки «ценой исправления одной уязвимости» некорректно.
Как одна проверка доступа превращается в большой проект
Представим сервис, в котором сотрудники разных компаний обмениваются документами. Сервер проверяет, что посетитель вошёл в учётную запись, но забывает проверить принадлежность запрошенного документа. Пользователь подставляет другой идентификатор и получает чужой файл. Вход в систему подтвердил личность, однако права на конкретный документ никто не проверил.
Если команда замечает риск при проектировании, можно сразу выбрать общий механизм проверки доступа и правила разделения данных организаций. Если ошибка обнаружилась в первой реализации, разработчик исправляет обработчик запроса и добавляет тест. Пока функция не разошлась по другим частям продукта, область переделки остаётся ограниченной.
Перед выпуском выясняется, что документы выдают несколько сервисов, отдельная функция выгружает архивы, а мобильное приложение использует другой путь скачивания. Теперь нужно найти все варианты доступа, проверить совместимость и повторить испытания. Исправление одной функции уже не доказывает, что соседние функции защищены.
После утечки возникает дополнительный вопрос, на который исправленный код не отвечает. Какие документы успели скачать? Если приложение не записывало достаточно сведений о доступе, точный масштаб может остаться неизвестным. Поэтому ранняя работа по безопасности должна охватывать и журналы событий, и ограничения прав, и объём сохраняемых данных. Хорошая архитектура помогает как предотвратить атаку, так и разобраться в последствиях.
Equifax и обновление, которое осталось поручением
В 2017 году злоумышленники проникли в системы кредитного бюро Equifax через уязвимость Apache Struts, компонента для разработки веб-приложений. О проблеме компания узнала в марте, а основной период компрометации пришёлся на май и июль. В материалах американских регуляторов масштаб утечки оценён примерно в 147 млн человек.
Показательная деталь связана с внутренним процессом. Служба безопасности потребовала исправить уязвимые системы в течение 48 часов после предупреждения, но компания не обеспечила проверку исполнения. Поручение существовало, уязвимое приложение продолжало работать. Расследования также выявили недостатки обнаружения атак и ограничения доступа между системами.
В 2019 году Equifax согласилась на урегулирование претензий на сумму не менее 575 млн долларов с возможным увеличением до 700 млн. Сумма включала помощь потребителям и выплаты регуляторам и штатам. Считать её стоимостью установки обновления или полным итоговым ущербом компании нельзя.
Случай Equifax прежде всего показывает провал управления уязвимостями уже работающей системы. Одной проверки исходного кода перед выпуском здесь недостаточно. Практический вывод для DevSecOps состоит в непрерывной связи между составом приложения, новыми сведениями об уязвимостях, ответственным владельцем и подтверждённым обновлением работающих экземпляров. Задачу следует закрывать после проверки результата, а не после отправленного письма.
TalkTalk и страницы, пережившие контроль над ними
В октябре 2015 года атакующие получили доступ к персональным данным 156 959 клиентов британского оператора TalkTalk. Для 15 656 клиентов утечка включала номера банковских счетов и банковские коды. Атака использовала SQL-инъекцию, при которой приложение позволяет постороннему вводу изменить смысл команды к базе данных.
По результатам технического расследования, входной точкой стали три страницы, доставшиеся TalkTalk после покупки британского бизнеса Tiscali в 2009 году. Программное обеспечение базы данных устарело, причём исправление одной из использованных ошибок было доступно более трёх с половиной лет. В июле и сентябре 2015 года происходили предыдущие SQL-инъекции, но недостаточное наблюдение за страницами не позволило компании своевременно отреагировать.
Здесь ранняя защита начинается с безопасного способа обращения к базе. Например, параметризованные запросы отделяют передаваемые значения от команд. Однако старый сайт не станет защищённым от того, что новые проекты получили хорошие шаблоны. У действующих страниц должны быть владелец, понятное назначение, актуальные компоненты и процедура вывода из эксплуатации.
TalkTalk напоминает о неприятном ограничении. Безопасность нового кода не покрывает всё, что компания продолжает держать в интернете. Обе истории показывают накопившиеся пробелы в защите, но не доказывают, что внедрение процесса с названием DevSecOps гарантированно предотвратило бы взлом. Полезно разбирать конкретные меры, которые могли разорвать цепочку атаки.
Как выглядит DevSecOps в повседневной работе
Практический процесс строят вокруг жизненного цикла изменения. Команда обсуждает новую функцию, пишет код, собирает приложение, проверяет результат и выпускает обновление. На каждом этапе нужны подходящие проверки, понятные исполнители и заранее согласованные условия, при которых выпуск придётся остановить.
Набор проверок должен зависеть от продукта. Для внутреннего справочника и публичного сервиса, который хранит финансовые документы, глубина проверки будет различаться. Полезную основу дают рекомендации OWASP, но конкретные правила команда выбирает с учётом архитектуры и возможного ущерба.
- До написания кода. Определить защищаемые данные, роли пользователей и опасные сценарии. Для новой функции экспорта обсудить, кто вправе выгружать данные, в каком объёме и какие события нужно записывать.
- При проверке изменений. Искать случайно добавленные пароли и ключи доступа, запускать статический анализ кода, или SAST. Такой анализ изучает программу без её обычного запуска и помогает находить определённые классы ошибок.
- При сборке. Проверять сторонние библиотеки и их зависимости. Анализ состава приложения, или SCA, сопоставляет используемые компоненты с известными проблемами. Найденное совпадение ещё требует оценки применимости.
- На тестовом стенде. Проверять работающее приложение. Динамический анализ, или DAST, исследует доступные функции через запросы. Отдельные тесты должны проверять роли, запреты и доступ к чужим объектам.
- Перед выпуском. Убедиться, что проверена именно выпускаемая сборка, настройки подходят для рабочей среды, а доступ к данным ограничен. Проверить возможность безопасно отменить неудачное изменение.
- После выпуска. Следить за атаками и новыми уязвимостями компонентов, проверять действующие настройки и доставлять исправления в работающие системы.
Сами средства автоматической сборки и доставки изменений, обычно называемые CI/CD, тоже требуют защиты. Если посторонний может изменить сценарий сборки или похитить её служебный ключ, чистый исходный код не спасёт выпускаемую программу. Нужны ограниченные права, контроль изменений, защищённое хранение секретов и разделение доверенных и недоверенных задач.
Автоматические проверки дополняют ручную работу. Сканер может не понять, что скидку разрешено использовать только один раз или что менеджер вправе видеть документы исключительно своего филиала. Такие правила нужно явно описывать, проверять тестами и разбирать со специалистами. Проверки на проникновение помогают оценить, как отдельные слабости складываются в практически осуществимую атаку.
Почему покупка сканера ещё не меняет процесс
Представим, что компания подключила анализатор и получила несколько тысяч предупреждений. Отчёт направили разработчикам без объяснения приоритетов, времени на исправления не выделили, а каждое новое предупреждение стало блокировать выпуск. Инструмент работает, но команда получила дополнительную очередь неопределённых задач.
У найденной проблемы должны быть владелец, понятное описание, условия воспроизведения и обоснованный приоритет. Уязвимость в доступной из интернета функции, через которую можно читать клиентские документы, обычно требует другого отношения, чем совпадение с записью о библиотеке, опасная возможность которой в приложении не используется. При этом недоступность уязвимого кода нужно подтвердить, а не предположить.
Для начала полезно отделить накопленные проблемы от новых. Старые находки получают план исправления, новые изменения проходят согласованные проверки. Блокировать выпуск разумно при подтверждённом неприемлемом риске или нарушении обязательного правила. Исключение должно иметь ответственного, срок и меры, которые временно уменьшают опасность.
Особенно опасна подмена результата удобной метрикой. Если команду оценивают только по числу закрытых предупреждений, разработчики могут заняться самыми простыми находками. Если требуют ноль предупреждений, появляется соблазн отключить шумное правило. Цель процесса состоит в снижении реального риска при предсказуемом выпуске изменений.
С чего начать и как проверить пользу
Для первого внедрения удобно выбрать один действующий сервис, у которого есть ответственная команда и регулярные изменения. Составить список компонентов, проверить обращение с секретами, разобрать доступ к данным и проследить путь обновления до рабочей среды. Такой разбор покажет конкретные разрывы, которые покупка ещё одного инструмента сама по себе не устранит.
Затем стоит договориться о нескольких обязательных проверках и измерить, сколько времени занимает обратная связь. Замечание к изменению полезно, пока разработчик помнит контекст и может быстро проверить исправление. Если результаты приходят через несколько дней отдельным отчётом, значительная часть преимущества ранней проверки теряется.
- Время до исправления. Считать срок от подтверждения проблемы до устранения в работающей системе. Отдельно смотреть критичные случаи и затянувшиеся задачи, а не только среднее значение.
- Проблемы после выпуска. Отслеживать, какие ошибки проходят ранние проверки и почему. После разбора добавлять тест или менять инженерное правило.
- Полнота охвата. Проверять, какая доля репозиториев, сборок и действующих сервисов действительно участвует в процессе.
- Цена проверок. Измерять задержки, ложные срабатывания и время специалистов на разбор предупреждений.
- Повторяемость ошибок. Искать классы проблем, которые возвращаются. Повторение может означать, что команде нужен безопасный общий компонент, а не очередная лекция.
Оценивать экономию лучше по собственным данным. Для нескольких исправлений можно записать трудозатраты, число затронутых команд, повторные проверки и внеплановую работу. Затем сравнить похожие проблемы, найденные до выпуска и после него. Такие измерения полезнее обещания сэкономить ровно в сто раз на любой уязвимости.
DevSecOps перестаёт быть модным словом, когда меняет конкретный рабочий день. Разработчик получает замечание вовремя, специалист по безопасности влияет на устройство функции, обновление доходит до сервера, а у старого приложения остаётся ответственный владелец. Компания платит за плановую инженерную работу и уменьшает вероятность гораздо более дорогой задачи, когда вместе с программой приходится восстанавливать доверие клиентов.