Skip to main content

Безопасное использование pull_request_target

Узнайте о рисках pull_request_target eventбезопасности .

Это руководство поможет оценить, стоит ли вашему рабочему процессу использовать это pull_request_target событие и понять связанные с этим риски безопасности. Также объясняется, что защита GitHub применяется к actions/checkout версии 7 и более поздней версии для снижения этих рисков по умолчанию, и когда следует отказаться от этой защиты при необходимости.

Читайте pull_request_target перед тем, как брать код pull request из одного из этих рабочих процессов или до того, как устанавливать allow-unsafe-pr-checkout ввод на actions/checkout.

Риски события pull_request_target

Рабочие процессы, запускаемые pull_request_target при повышенном доверии: задание получает базовые репозитории GITHUB_TOKEN, доступ к секретам репозитория и организации, а также доступ к кэшу по умолчанию. Это то же доверие, которое оказывается подобным событиям push , которое могут активировать только соавторы, и именно оно полезно pull_request_target для автоматизации, отвечающей на pull запросы с форков, такие как маркировка, триаж или публикация аутентифицированных проверок состояния.

Чтобы понять, почему это безопасно по умолчанию и как эта защита часто нарушается, ознакомьтесь pull_request_target с pull_request.

Событие pull_request (вместе с pull_request_review и pull_request_review_comment) необычно: оно запускает файл рабочего процесса из коммита слияния pull request. Для pull-запроса, открываемого из форка, этот коммит контролируется кем-то без доступа к записи в базовый репозиторий. Для безопасного запуска кода ненадёжного рабочего процесса эти GitHub события ограничиваются только для чтения GITHUB_TOKEN, запрещают доступ к другим секретам и применяют политики одобрения форка для предотвращения злоупотреблений вычислительной системой. Дополнительные сведения см. в разделе События, инициирующие рабочие процессы. По умолчанию actions/checkout в pull_request workflow также проверяется коммит слияния pull request, так что код проверен, и рабочий процесс, который запускается, остаются последовательными.

pull_request_target Вносит одно важное и тонкое изменение: рабочий процесс и любой последующий actions/checkout вызов, не указанный ref, берутся из стандартной ветки базового репозитория, а не из pull-запроса. Поскольку работает только доверенный код из стандартной ветки, безопасно предоставлять секреты и токен чтения/записи. По умолчанию код с форка не выполняется.

Возникает риск, когда автор рабочего процесса переопределяет это по умолчанию для запуска кода форка. Разработчики часто выбирают pull_request_target это, потому что хотят запускать pull request форка через CI и иметь доступ к секретам, например, для тестирования, требующего приватного реестра. Для этого они указывают actions/checkout на заголовок pull request, а не на стандартную ветку, которая небезопасна:

# INSECURE. Provided as an example only.
on:
  pull_request_target:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - name: Test
        run: make test

Сам шаг проверки не выполняет недоверенный код. Сам файл рабочего процесса всё равно взят из стандартной ветки. Уязвимость завершается следующим шагом, который запускает код, проверенный в текущей рабочей директории. Здесь make test выполняется Makefile захват с головы запроса на вытяжение. Злоумышленнику достаточно открыть pull request от форка, чей Makefile (или скрипт сборки, тестовая команда, файл зависимостей или конфигурации) содержит вредоносные команды. Эти команды затем запускаются с секретами и токена базового репозитория.

Эта схема известна как «pwn-запрос» и стала коренной причиной множества компромиссов в цепочке поставок. Для получения дополнительной информации см . раздел «Предотвращение запросов pwn из GitHub Security Lab. Распространённые уязвимые формы включают:

  • Проверка головы pull-запроса или коммита слияния в actions/checkout (ref: ${{ github.event.pull_request.head.sha }}, ref: refs/pull/${{ github.event.pull_request.number }}/merge) и затем сборка, тестирование или иным способом выполнения результата.
  • Установка repository: на вилку (repository: ${{ github.event.pull_request.head.repo.full_name }}) для прямого оттягивания ветви вилки.
  • Получение кода pull-запроса вне ( actions/checkout например, с git fetch, gh pr checkoutили скачивание артефакта из запуска pull_request форка) и его запуск.

Запросы Pwn также не уникальны для pull_request_target. Любое событие с секретами может вводить запрос pwn, если он проверяется или скачает и выполняет ненадёжный код. Например, рабочий процесс OR issue_comment``workflow_run , который загружает и запускает код pull-запроса форка, уязвим аналогично. Рабочий workflow_run процесс должен рассматривать артефакты, загруженные другими рабочими процессами, как ненадёжные данные, поскольку их содержимое может быть получено из форка.

Решение о том, использовать ли pull_request_target

Некоторые рабочие процессы требуют проверки fork-pull request-кода с повышенным доверием, и именно поэтому pull_request_target он был создан изначально. Например, генерация отчетов о покрытии, требующих приватного реестра артефактов, или создание и проведение аутентифицированных проверок изменений, введённых в pull request. Рассмотрите вопросы ниже перед использованием pull_request_target или подключением allow-unsafe-pr-checkout к флагу в actions/checkout.

  • Можете ли вы использовать pull_request вместо этого? pull_request триггерирует на тех же событиях, что pull_request_target и запускает код рабочего процесса из pull_request ветки слияния. Он делает это безопасно при pull request-запросах с форков с описанными выше защитой. Если дополнительный секретный доступ не требуется, используйте pull_request. Более сложные рабочие процессы можно реструктурировать, чтобы отделить потенциально опасные обработки pull request-кода от доступа к секретам. Для получения дополнительной информации см . раздел «Предотвращение запросов pwn из GitHub Security Lab.

  • Выполняется ли когда-нибудь проверенный код? Это уязвимость, которая вводит уязвимости при запросе pwn. Чаще всего это вводится actions/checkout через запуск головы pull request в рабочую директорию и его запуск. Если path вход не установлен, actions/checkout он записывает код в $GITHUB_WORKSPACE каталог, который обычно является рабочей директорией, где выполняются последующие команды. Выполнение не ограничивается вашими собственными этапами: команды сборки и тестирования, такие как npm install и npm run build, а также конфигурационные файлы и зависимости, которые код приносит с собой, могут запускать код, управляемый злоумышленниками. Реализация не требует очевидного этапа сборки. Вы должны убедиться, что снятый код проверяется только как данные и никогда не выполняется до использования pull_request_target события.

Ужесточение pull_request_target рабочего процесса

Если вы подтвердили, что это pull_request_targetнужно, примените эти меры контроля, чтобы ограничить влияние этого высокорискового события. Они применимы независимо от того, соответствует ли ваш рабочий процесс коду pull request.

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

  • Понимайте влияние кэширования. Помимо GITHUB_TOKEN и настроенных секретов, рабочие процессы, работающие на pull_request_target , также имеют доступ к записи кэша, который разделяется с другими рабочими процессами на ветке по умолчанию. Вредоносные изменения этого кэша из-за pull_request_target событий могут повлиять на выполнение других, не связанных между собой рабочих процессов.

  • Убедитесь, что исходные вычисления являются изолированными и эфемерными. Если используются самостоятельные бегуны, необходимо убедиться, что среда для бегунов надлежащим образом ограничена от внутренних ресурсов и не используется повторно на протяжении GitHub Actions всех забегов. Дополнительные сведения см. в разделе Справочник по безопасному использованию.

  • Ворота отстают от одобрения. pull_request_target Рабочие процессы могут быть ограничены требованием label , которое могут добавлять только пользователи с доступом к записи. Это подробно описано в GitHub Security Labруководстве по предотвращению запросов PWN.

  • Соблюдайте GitHub Actions лучшие практики безопасности. Помимо специфических рисков pwn-запросов, могут существовать и другие распространённые уязвимости, такие как инъекция команд, которые влияют на код, выполняемый в этом привилегированном событии. Для получения дополнительной информации см. раздел «Сохранить безопасность ваших GitHub Actions and workflows: Ненадёжный ввод от GitHub Security Lab. Для выявления и проактивной защиты от распространённых GitHub Actions уязвимостей включите CodeQL .GitHub Actions Дополнительные сведения см. в разделе Настройка настройки по умолчанию для сканирования кода.

Отказ от встроенных средств защиты

Если вы проработали вопросы выше и убедились, что ваш рабочий процесс требует pull_request_target и использует его безопасно, вы можете отказаться от actions/checkout защиты. Настройка allow-unsafe-pr-checkout: true как actions/checkout вход позволяет проверять ссылки на головы pull request с форков. Сделайте это только после подтверждения того, что проверенный код так и не выполнен. Входные данные специально названы так, чтобы его было легко заметить при проверке кода и статическом анализе.

Эта защита покрывает только ссылки на pull request fork. Проверка другого ненадёжного кода, например, не связанного стороннего репозитория, получение кода с git fetch помощью или gh pr checkout, или запуск загруженного артефакта, не подпадает под эти actions/checkout проверки.

Ограничение использования pull_request_target

Администраторы репозиториев, организаций и предприятий могут использовать защиту от выполнения рабочих процессов для контроля, какие события и акторы могут запускать рабочие процессы. Если репозиторий не имеет законного применения , pull_request_targetограничение устраняет риск независимо от того, как написаны отдельные рабочие процессы.