Любой может получить доступ к удалённым и приватным данным репозиториев GitHub

Специальный корреспондент
Собака

Собака

Пресс-служба
Команда форума
Private Club
Регистрация
13/10/15
Сообщения
55.157
Репутация
63.040
Реакции
277.488
RUB
0


Кто угодно может получать доступ к данным из удалённых форков, удалённых репозиториев и даже приватных репозиториев GitHub. И эти данные доступны всегда. Это известно разработчикам GitHub, и они намеренно спроектировали систему таким образом.

Это настолько огромный вектор атак для всех организаций, использующих GitHub, что мы решили ввести новый термин: Cross Fork Object Reference (CFOR). Уязвимость CFOR возникает, когда форк одного репозитория может получить доступ к требующим защиты данным из другого форка (в том числе и к данным из приватных и удалённых форков). Аналогично Insecure Direct Object Reference, при CFOR пользователи передают хэши коммитов, чтобы напрямую получать доступ к данным коммитов, которые иначе были бы для них невидимыми.

Давайте рассмотрим несколько примеров.


Получение доступа к данным удалённых форков​


Возьмём такую часто используемую в GitHub последовательность действий:


  1. Пользователь создаёт форк публичного репозитория.
  2. Далее он выполняет коммит кода в свой форк.
  3. Он удаляет свой форк.


ctccznbise9i8q5u9_hvjawyyuw.png


Доступен ли по-прежнему код, коммит которого был выполнен в форк? Вроде бы не должен быть, правда? Мы ведь его удалили.

Но он доступен. И будет доступен всегда. Вне вашего контроля.

В показанном ниже видео мы создаём форк репозитория, коммитим в него данные, удаляем форк, а затем получаем доступ к «удалённым» данным коммита через исходный репозиторий.



Вы можете подумать, что защищены необходимостью знать хэш коммита. Но это не так. Хэш можно узнать, подробнее об этом ниже.


▍ Как часто можно находить данные из удалённых форков?​


Достаточно часто. Мы изучили три часто форкаемых публичных репозиторя крупной ИИ-компании, и с лёгкостью нашли 40 валидных ключей API из удалённых форков. Похоже, пользователи применяли такой паттерн:


  1. Создавали форк репозитория.
  2. Прописывали ключ API в файле примера.
  3. Выполняли нужные им действия.
  4. Удаляли форк.


1mtagp0ltdlzmmuqrpxim7dw8yi.png


Но ещё хуже, что можно сделать и наоборот:


Доступ к данным удалённых репозиториев​


Рассмотрим следующий сценарий:


  1. У вас есть публичный репозиторий GitHub.
  2. Пользователь создаёт форк этого репозитория.
  3. Вы коммитите данные после того, как он создал форк (и он никогда не синхронизирует свой форк с вашими обновлениями).
  4. Вы удаляете репозиторий целиком.


mdjvu4jf78e3-tfeje_j6the1mo.png


Будет ли код, который вы закоммитили после форка, по-прежнему доступным?

Да.

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


eomtwfzi09oamnif3jz6mygnx0a.png


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



И это не просто какой-то пограничный сценарий. Вот, что произошло у меня недавно:

Я отправил уязвимость уровня P1 крупной технологической компании, показав, что она случайно закоммитила приватный ключ к аккаунту GitHub сотрудника, имеющего высокий уровень доступа к GitHub всей организации. Компания немедленно удалила репозиторий, но поскольку к нему создавались форки, я всё равно смог получить через форк доступ к коммиту, содержащему конфиденциальные данные, хотя форк никогда не синхронизировался с исходным upstream-репозиторием.

Из этого следует сделать вывод, что любой код, закоммиченный в публичный репозиторий, будет доступен вечно, пока существует хотя бы один форк этого репозитория.

Но и это ещё не всё.


Получение доступа к данным приватных репозиториев​


Рассмотрим часто используемый процесс вывода нового инструмента в open source на GitHub:


  1. Вы создаёте приватный репозиторий, который позже будет сделан публичным.
  2. Далее создаёте приватную внутреннюю версию этого репозитория (форкнув его) и коммитите дополнительный код фич, которые не будете делать публичными.
  3. Вы делаете upstream-репозиторий публичным и оставляете форк приватным.


twgqf2bij99oj7idoohll6imhce.png


Будут ли приватные фичи и связанный с ними код (из шага 2) видны широкой публике?

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

Все коммиты, внесённые в приватный форк после того, как вы сделали upstream-репозиторий публичным, доступны не будут. Это вызвано тем, что изменение видимости приватного upstream-репозитория приводит к созданию двух сетей репозиториев — одной для приватной версии, другой — для публичной.


yhj5q8bhrxy8ayzkvxt33jlmsv4.png


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



К сожалению, именно так чаще всего пользователи и организации подходят к разработке опенсорсного ПО. Из-за этого возможно непреднамеренное раскрытие конфиденциальных данных и секретов в публичных репозиториях GitHub организации.


Как же получить доступ к данным?​


Операции уничтожения в сети репозиториев GitHub (подобные описанным в трёх приведённых выше сценариях) удаляют ссылки на данные коммитов из стандартного UI GitHub и обычных операций git. Однако эти данные всё равно существуют, и к ним можно получить доступ (если знать хэш коммита). В этом заключается связь между уязвимостями CFOR и IDOR — если вы знаете хэш коммита, то сможете напрямую получать доступ к данным, не предназначенным для вас.

Хэши коммитов — это значения SHA-1.


ghe_2ui2huylgo6wpo5-bvbisxo.png


Если пользователь знает хэш SHA-1 конкретного коммита, который он хочет просмотреть, то он может напрямую перейти к этому коммиту в конечной точке: <user/org>/<repo>/commit/<commit_hash>. Он увидит жёлтый баннер с информацией о том, что «этот коммит не принадлежит ни к одной из ветвей этого репозитория и может принадлежать форку вне репозитория».


wfapchtbhdae3awf6oua_fry-p4.png


Откуда взять эти значения хэшей?

Хэши коммитов можно подобрать брутфорсом через UI GitHub, и в особенности потому, что протокол git допускает использование при ссылках на коммит. Короткое значение SHA-1 — это минимальное количество символов, необходимое для предотвращения коллизий с хэшем другого коммита. Абсолютно минимальное значение равно 4. Пространство ключей всех значений SHA-1 из четырёх символов составляет 65536 (16^4). Брутфорс всех возможных значений можно выполнить достаточно просто.

Рассмотрим для примера этот коммит из нашего репозитория:


wafwb-yultsq9ddr0dnlcoed1wm.png


Для получения доступа к этому коммиту пользователи обычно переходят к URL, содержащему полный хэш SHA-1 коммита: .

Но им необязательно знать всё значение SHA-1 из 32 символов, достаточно лишь правильно угадать короткое значение SHA-1, которое в данном случае равно 07f01e.


czcovgcasfuphluks21avubwi8w.png




Но вот, что ещё более интересно: GitHub раскрывает публичную конечную точку API событий. Можно также запрашивать хэши коммитов в , управляемом третьей стороной. Он сохраняет все события GitHub за последний десяток лет вне пределов GitHub даже после удаления репозиториев.


Политики GitHub​


Недавно мы отправили отчёт о своих находках в GitHub в рамках его программы VDP. Был получен следующий ответ:


sgp3g1qondtb5w_3x2w0dupzy1o.png


После изучения документации стало абсолютно понятно, что GitHub осознанно спроектировал репозитории таким образом.


bkzwhxhqqr0ygmob_ykqtqdoevs.png



dwyxedfp94yqapj2ojqu1t6stjc.png




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

Но для нас проблема заключается в следующем:

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


Последствия​


Из этого можно сделать несколько выводов:


  1. Пока существует хотя бы один форк, любой коммит в эту сеть репозиториев (то есть коммиты в upstream-репозиторий или в downstream-форки) будет существовать вечно.
    • Это ещё больше убеждает нас в нашем мнении о том, что единственный способ устранить последствия утечки ключа в публичный репозиторий GitHub — это ротация ключей. Мы потратили много времени на документирование способов ротации ключей для самых популярных утёкших типов секретов, изучите нашу работу здесь: .
  2. Архитектура репозиториев GitHub нуждается в этих слабостях дизайна и, к сожалению, подавляющее большинство пользователей GitHub никогда не будет разбираться в том, как работает сеть репозиториев, что повредит их защите.
  3. Мы надеемся, что благодаря совершенствованию сканирования секретов мы сможем просканировать все коммиты в сети репозиториев и будем отправлять предупреждения о секретах, которые могут принадлежать не нам (например, они могут принадлежать тому, кто форкнул репозиторий). Это потребует более тщательной сортировки.
  4. Эти три сценария могут выглядеть пугающими, однако это не все способы, которыми GitHub способен хранить удалённые из репозиториев данные. В нашем рассказывается о том, что вам нужно сканировать на наличие секретов и удалённые ветви.







 
  • Теги
    github
  • Сверху Снизу