Рекомендации по обеспечению безопасности для цепочки поставок программного обеспечения
Открытый код можно встретить повсюду. Его можно найти во многих проприетарных базах кода и проектах сообщества. Для организаций и отдельных лиц вопрос уже не в том, используют ли они открытый код, а в том, какой именно открытый код и в каком объеме.
Если вы не знаете, что находится в вашей цепочке поставок программного обеспечения, уязвимость в одной из ваших зависимостей, находящейся выше по цепочке, может стать фатальной и привести к тому, что вы или ваши клиенты будут скомпрометированы. В этом документе подробно рассматривается понятие "цепочка поставок программного обеспечения" и ее значение и приводятся рекомендации по защите цепочки поставок вашего проекта.
Зависимости
Термин "цепочка поставок программного обеспечения" охватывает все компоненты, входящие в состав вашего программного обеспечения, и их источники. Это зависимости и свойства зависимостей, от которых зависит ваша цепочка поставок программного обеспечения. Зависимость — это то, что необходимо для выполнения программы. Это может быть код, двоичные файлы или другие компоненты, а также их источники, например репозиторий или диспетчер пакетов.
В зависимость включается информация о том, кто написал код, когда он был добавлен, как он был проверен на наличие проблем с безопасностью и известных уязвимостей, поддерживаемые версии, сведения о лицензиях и практически все, что связано с зависимостью в любой точке процесса.
Цепочка поставок также охватывает другие компоненты стека за рамками приложения, такие как сценарии сборки и упаковки или программное обеспечение, предоставляющее инфраструктуру, на основе которой работает ваше приложение.
Уязвимости
Сегодня зависимости программного обеспечения встречаются повсеместно. В проектах довольно часто используются сотни зависимостей с открытым кодом для функций, которые вам не приходится писать самостоятельно. Это может означать, что большая часть вашего приложения состоит из кода, написанного не вами.
Вы не можете контролировать возможные уязвимости в зависимостях сторонних разработчиков и в зависимостях с открытым кодом так же строго, как ваш собственный код, что может привести к потенциальным угрозам безопасности в цепочке поставок.
Если в одной из этих зависимостей есть уязвимость, ваше программное обеспечение также может стать уязвимым. И это может вызывать тревогу, так как ваши зависимости могут быть изменены даже без вашего ведома. Даже если сейчас в зависимости есть уязвимость, которую нельзя использовать, она может стать доступной для использования в будущем.
Возможность использования результатов работы нескольких тысяч разработчиков программ и авторов библиотек с открытым кодом означает, что тысячи незнакомых людей по сути дела могут вносить изменения прямо в ваш рабочий код. На ваш продукт в цепочке поставок программного обеспечения влияют уязвимости, которые не были устранены, безобидные ошибки и даже вредоносные атаки на зависимости.
Компрометация цепочки поставок
Традиционное определение цепочки поставок возникло в сфере производства. Цепочка поставок — это цепочка процессов, необходимых для создания и поставки чего-либо. Она включает планирование, поставку материалов, производство и розничную продажу. Цепочка поставок программного обеспечения похожа на цепочку поставок в сфере производства с той разницей, что вместо материалов в ней используется код. Вместо производства она включает разработку. Вместо добычи руды из недр земли она включает получение коммерческого или открытого кода от поставщиков, и в общем случае открытый код поступает из репозиториев. Добавление кода из репозитория означает, что ваш продукт зависит от этого кода.
Одним из примеров атаки на цепочку поставок программного обеспечения является ситуация, когда вредоносный код намеренно добавляется в зависимость, используя цепочку поставок этой зависимости, чтобы распространить вредоносный код жертвам атаки. Атаки на цепочки поставок происходят на самом деле. Существует множество методов атаки на цепочку поставок, от непосредственного добавления вредоносного кода от имени нового участника до получения контроля над учетной записью участника без ведома других пользователей и даже до компрометации ключа подписывания для распространения программного обеспечения, официально не являющегося частью зависимости.
Атака на цепочку поставок программного обеспечения сама по себе является редко является конечной целью. Скорее она дает злоумышленнику возможность добавления вредоносного кода или создания бэкдора для доступа в будущем.
Программное обеспечение, к которому не были применены исправления
Сегодня открытый код используется очень широко, и, скорее всего, он будет так же широко использоваться в будущем. Учитывая, что мы будем продолжать использовать программное обеспечение с открытым кодом, угрозой для безопасности цепочки поставок является программное обеспечение, к которому не применены исправления. Зная это, какие меры нужно предпринять, чтобы устранить риск наличия уязвимости в зависимости вашего проекта?
- Познакомьтесь с тем, что находится в вашей среде. Для этого необходимо определить все зависимости и все промежуточные зависимости вашего проекта и оценить риски этих зависимостей, например уязвимости или ограничения лицензирования.
- Управляйте зависимостями. При обнаружении новой уязвимости системы безопасности необходимо определить, затрагивает ли вас эта уязвимость, и если да, то установить последнюю версию программного обеспечения и доступные исправления для системы безопасности. Особенно важно отслеживать изменения, которые включают появление новых зависимостей, и регулярно выполнять аудит старых зависимостей.
- Отслеживайте цепочку поставок. Для этого выполняйте аудит средств контроля, используемых для управления зависимостями. Это позволит применить более строгие условия для ваших зависимостей.
Мы расскажем о различных средствах и методах, предоставляемых NuGet и GitHub, которые можно использовать для устранения потенциальных рисков вашего проекта.
Ознакомление с тем, что находится в вашей среде
Пакеты с известными уязвимостями
📦 Пользователь пакета | 📦🖊 Автор пакета
.NET 8 и Visual Studio 17.8 добавили NuGetAudit, которые будут предупреждать о прямых пакетах с известными уязвимостями во время восстановления. .NET 9 и Visual Studio 17.12 изменили значение по умолчанию, чтобы предупредить о транзитивных пакетах, а также.
NuGetAudit требует источника для предоставления известной базы данных уязвимостей, поэтому если вы не используете nuget.org в качестве источника пакета, его следует добавить в качестве источника аудита.
К тому времени, когда NuGet предупреждает вас, уязвимость общеизвестна. Злоумышленники могут использовать это публичное раскрытие информации для разработки атак для целевых объектов, которые не исправили свои приложения. Поэтому при появлении предупреждения о том, что в проекте используется пакет с известной уязвимостью, необходимо быстро выполнить действия.
Схема зависимостей NuGet
📦 Пользователь пакета
Просмотреть зависимости NuGet для проекта можно непосредственно в соответствующем файле проекта.
Обычно этот файл находится в одном из двух мест.
packages.config
— расположен в корневом каталоге проекта.<PackageReference>
— расположен в файле проекта.
В зависимости от того, какой метод используется для управления зависимостями NuGet, зависимости также можно просмотреть с помощью Visual Studio: непосредственно в Обозревателе решений или в диспетчере пакетов NuGet.
Для сред CLI можно использовать dotnet list package
команду для вывода списка зависимостей проекта или решения.
Вы также можете использовать dotnet nuget why
команду , чтобы понять, почему транзитивные пакеты (которые не ссылаются непосредственно на проект) включаются в граф пакетов проекта.
Дополнительные сведения об управлении зависимостями NuGet см. в следующей документации.
Диаграмма зависимостей GitHub
📦 Пользователь пакета | 📦🖊 Автор пакета
Схему зависимостей GitHub можно использовать для просмотра пакетов, от которых зависит ваш проект, и для просмотра репозиториев, которые зависят от вашего проекта. Это позволит найти и просмотреть все уязвимости, обнаруженные в зависимостях проекта.
Дополнительные сведения о зависимостях репозитория GitHub см. в следующей документации.
Версии зависимостей
📦 Пользователь пакета | 📦🖊 Автор пакета
Чтобы обеспечить безопасность цепочки поставок зависимостей, необходимо регулярно обновлять все зависимости и инструменты до последних стабильных версий, так как эти версии часто содержат новейшие функции и исправления безопасности для известных уязвимостей. Ваши зависимости могут включать код, от которого вы зависите, двоичные файлы и инструменты, которые вы используете, а также другие компоненты. Это может включать следующее:
Управление зависимостями
Нерекомендуемые зависимости NuGet и зависимости NuGet, содержащие уязвимости
📦 Пользователь пакета | 📦🖊 Автор пакета
С помощью dotnet CLI можно получить список всех известных нерекомендуемых зависимостей и зависимостей, содержащих уязвимости, в вашем проекте или решении.
Вы можете использовать команду dotnet list package --deprecated
или dotnet list package --vulnerable
для получения списка всех известных нерекомендуемых зависимостей и зависимостей, содержащих уязвимости.
NuGetAudit может предупредить вас об известных уязвимых зависимостях и включить по умолчанию, когда источник предоставляет базу данных уязвимостей.
Зависимости GitHub, содержащие уязвимости
📦 Пользователь пакета | 📦🖊 Автор пакета
Если проект размещен на сайте GitHub, вы можете использовать систему GitHub Security, чтобы найти уязвимости безопасности и ошибки в вашем проекте, и Dependabot исправит их, открыв запрос на вытягивание для вашей базы кода.
Перехват зависимостей, содержащих уязвимости, до их появления является одной из целей подхода "Сдвиг влево". Возможность получить сведения о зависимостях, таких как лицензия, промежуточные зависимости и возраст зависимостей, поможет вам сделать именно это.
Дополнительные сведения об оповещениях и обновлениях для системы безопасности Dependabot см. в следующей документации.
Веб-каналы NuGet
📦 Пользователь пакета
Используйте источники пакетов, которыми вы доверяете. При использовании нескольких общедоступных и частных веб-каналов исходного кода NuGet пакет можно скачать из любого веб-канала. Чтобы гарантировать, что сборка является предсказуемой и защищенной от известных атак, таких как Путаница зависимостей, необходимо знать, из каких конкретных веб-каналов поступают ваши пакеты. Для защиты можно использовать один веб-канал или частный веб-канал с возможностями восходящего потока.
Дополнительные сведения о защите веб-каналов пакета см. в разделе Три способа снижения риска при использовании частных веб-каналов пакетов.
При использовании частного веб-канала ознакомьтесь с рекомендациями по обеспечению безопасности для управления учетными данными.
Политики доверия клиентов
📦 Пользователь пакета
Существуют политики, которые можно принять и которые требуют подписывания пакетов, используемых вами. Это позволяет доверять автору пакета при условии, что пакет подписан автором, или доверять пакету, если он принадлежит определенному пользователю или учетной записи, которая соответствует репозиторию, подписанному NuGet.org.
Сведения о настройке политик доверия клиентов см. в следующей документации.
Файлы блокировки
📦 Пользователь пакета
В файлах блокировки хранится хэш содержимого пакета. Если хэш содержимого пакета, который необходимо установить, совпадает с хэшем в файле блокировки, это подтверждает воспроизводимость пакета.
Сведения о включении блокировки файлов см. в следующей документации.
Сопоставление источников пакетов
📦 Пользователь пакета
Сопоставление источников пакетов позволяет централизованно объявлять, из какого источника будет восстанавливаться каждый пакет в решении в файле nuget.config.
Сведения о том, как включить сопоставление источников пакетов, см. в следующей документации.
Безопасные компьютеры
Разрешения каталога
📦 Пользователь пакета
В Windows и Mac, а также некоторые дистрибутивы Linux, каталоги домашней учетной записи пользователя по умолчанию являются частными. Однако некоторые дистрибутивы Linux делают каталоги пользователей читаемыми другими учетными записями на том же компьютере по умолчанию. Кроме того, существует несколько вариантов конфигурации для перенаправления глобальной папки пакетов NuGet и кэша HTTP в расположения, отличные от по умолчанию. Решения, проекты и репозитории также могут быть созданы за пределами домашнего каталога пользователя.
Если вы используете пакеты, которые не находятся в nuget.org, то если любая другая учетная запись на компьютере может считывать глобальные пакеты NuGet или каталоги кэша HTTP или выходной каталог сборки проекта, эти пакеты могут быть раскрыты пользователям, которые не должны иметь доступа к этим пакетам.
В Linux измените разрешения файла nuget.config, dotnet nuget update source
чтобы сделать его доступным только для чтения владельцем файла.
Тем не менее, если изменить файл nuget.config каким-либо другим способом, и файл находится в расположении, где другие учетные записи могут считывать файл, может быть информация о раскрытии информации о URL-адресе источника пакета или учетных данных источника пакета.
Необходимо убедиться, что любой файл конфигурации nuget.config не может быть прочитан другими пользователями того же компьютера.
Решения в каталоге загрузки
📦 Пользователь пакета
При работе с решениями или проектами в каталоге скачиваемых файлов следует учитывать дополнительные сведения. NuGet накапливает параметры из нескольких файлов конфигурации, и MSBuild обычно импортирует Directory.Build.props, Directory.NuGet.props, Directory.Build.targets и потенциально другие файлы из любого родительского каталога прямо до корневого каталога файловой системы.
Папка загрузки имеет дополнительный риск, так как обычно это расположение по умолчанию, которое веб-браузеры будут загружать файлы из Интернета.
Агенты сборки
📦 Пользователь пакета
Агенты сборки (агенты CI), которые не сбрасываются в исходное состояние после каждой сборки, имеют несколько рисков, которые необходимо учитывать.
Сведения о безопасных способах управления учетными данными см. в документации по потреблению пакетов из проверенных веб-каналов.
Сведения об изменении каталогов, в которые NuGet хранятся данные, см . в документации по управлению глобальными пакетами, кэшем и временными папками. Эти каталоги должны быть настроены в каталог, который агент CI очищает после каждой сборки.
Обратите внимание, что все пакеты, используемые проектом, могут оставаться в выходном каталоге сборки проекта. Если в проекте используются пакеты из проверенных источников, другие пользователи того же агента CI могут получить несанкционированный доступ к сборкам пакетов. Поэтому вы также должны очистить репозиторий в конце сборки, даже если сборка завершается сбоем или отменена.
Отслеживание цепочки поставок
Сканирование секретов GitHub
📦🖊 Автор пакета
GitHub проверяет репозитории на наличие ключей API NuGet, чтобы предотвратить неправомерное использование секретов, которые были зафиксированы случайно.
Дополнительные сведения о проверке секретов см. в разделе Проверка секретов.
Подписывание пакета автором
📦🖊 Автор пакета
Подписывание автором позволяет автору пакета создать отметку со своим удостоверением в пакете, а пользователю пакета — проверить, что пакет создан именно этим автором. Это защищает вас от неправомерного изменения содержимого пакета и служит единым источником истинности происхождения и подлинности пакета. Сочетание подписывания с политиками доверия клиентов позволяет проверить, что пакет создан указанным автором.
Чтобы подписать пакет от лица автора, см. раздел Подписывание пакета.
Воспроизводимые сборки
📦🖊 Автор пакета
Воспроизводимые сборки создают двоичные файлы, которые полностью идентичны при каждой сборке и содержат ссылки на исходный код и метаданные компилятора, позволяющие потребителю пакета повторно создавать двоичный файл и напрямую проверять, что среда сборки не скомпрометирована.
Дополнительные сведения о воспроизводимых сборках см. в статьях Создание пакетов с исходной ссылкой и Воспроизводимая проверки сборки.
Двухфакторная проверка подлинности (2FA)
📦🖊 Автор пакета
Каждая учетная запись в nuget.org включена 2FA. Это добавляет дополнительный уровень безопасности при входе в учетную запись GitHub или учетную запись NuGet.org.
Резервирование префикса ИД пакета
📦🖊 Автор пакета
Чтобы защитить удостоверение пакета, можно зарезервировать префикс идентификатора пакета с соответствующим пространством имен, чтобы связать пакет с соответствующим владельцем. Для этого префикс идентификатора пакета должен соответствовать определенным критериям.
Дополнительные сведения о резервировании префиксов идентификаторов см. в разделе Резервирование префикса идентификатора пакета.
Объявление нерекомендуемым и удаление из списка пакета, содержащего уязвимости
📦🖊 Автор пакета
Если вы знаете, что созданный вами пакет содержит уязвимость, то для защиты экосистемы пакетов .NET необходимо предпринять все возможные меры для того, чтобы объявить пакет нерекомендуемым и удалить его из списка, чтобы этот пакет не отображался при поиске пакетов пользователями. Если вы используете пакет, который является нерекомендуемым и был удален из списка, следует перестать использовать этот пакет.
Сведения о том, как объявить пакет нерекомендуемым и удалить его из списка, см. в следующей документации по объявлению пакетов нерекомендуемыми и удалению пакетов из списка.
Кроме того, рассмотрите возможность создания отчетов в базе данных помощников по GitHub.
Итоги
Цепочка поставок программного обеспечения — это все, что входит в ваш код и влияет на него. Несмотря на то что компрометация цепочек пакетов является реальностью и ее популярность растет, случаи такой компрометации все еще встречаются редко. Поэтому самыми важными мерами, которые вы можете предпринять для защиты цепочки поставок, являются ознакомление с зависимостями, управление зависимостями и отслеживание цепочки поставок.
Вы познакомились с различными методами, предоставляемыми NuGet и GitHub и используемыми для повышения эффективности при просмотре и отслеживании цепочки поставок, а также при управлении цепочкой поставок.
Дополнительные сведения о защите программного обеспечения во всем мире см. в Отчете о безопасности The State of the Octoverse 2020 .