Уязвимость в RubyGems.org, позволяющая подменить чужие пакеты

В репозитории пакетов RubyGems.org выявлена критическая уязвимость (CVE-2022-29176), позволяющая без наличия должных полномочий подменить некоторые чужие пакеты в репозитории путём инициирования изъятия (yank) легитимного пакета и загрузки вместо него другого файла с тем же именем и номером версии.

Для успешной эксплуатации уязвимости необходимо выполнения трёх условий:

  • Атака может быть совершена только на пакеты, в имени которых используется символ тире.
  • Атакующий должен иметь возможность разместить gem-пакет с частью имени до символа тире. Например, если атака производится на пакет “rails-html-sanitizer”, атакующий должен разместить в репозитории собственный пакет “rails-html”.
  • Пакет, на который совершается атака, должен быть создан в последние 30 дней или не обновляться в течение 100 дней.

Уязвимость вызвана ошибкой в обработчике действия “yank”, трактующего часть имени после тире как название платформы, что позволяло инициировать удаление чужих пакетов, совпадающих в части имени до символа тире. В частности, в коде обработчика операции “yank” для поиска пакетов использовался вызов ‘find_by!(full_name: “#{rubygem.name}-#{slug}”)’, при том, что параметр “slug” передавался владельцем пакета для определения удаляемой версии. Владелец пакета “rails-html” вместо версии “1.2.3” мог указать “sanitizer-1.2.3”, что привело бы к применению операции к чужому пакету “rails-html-sanitizer-1.2.3”.

Проблема была выявлена исследователем безопасности в рамках действующей на HackerOne программы выплаты вознаграждений за поиск проблем с безопасностью в известных открытых проектах. Проблема устранена в RubyGems.org 5 мая и по заявлению разработчиков они пока не выявили следов эксплуатации уязвимости в логах за последние 18 месяцев. При этом пока проведён лишь поверхностный аудит и в дальнейшем планируется проведение более глубокой проверки.

Для проверки своих проектов рекомендуется проанализировать историю операций в файле Gemfile.lock, вредоносная активность выражается в наличии изменений с сохранением имени и версии или сменой платформы (например, когда пакт gemname-1.2.3 обновлён до gemname-1.2.3-java). В качестве обходного метода защиты от скрытой подмены пакетов в системах непрерывной интеграции или при публикации проектов разработчикам рекомендовано использовать Bundler с опциями “–frozen” или “–deployment” для фиксации зависимостей.

Release. Ссылка here.