Код-ревью Senior CI: пайплайны и артефакты обновлено

Код-ревью: workflow GitHub Actions

Вопрос

Workflow запускается на пул-реквесты, в том числе из форков публичного репозитория. Найдите проблемы.

name: build
on:
  pull_request_target:
permissions: write-all
jobs:
  build:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - uses: some-org/setup-tool@master
      - run: npm install
      - run: npm test
      - run: echo "Deploy token ${{ secrets.DEPLOY_TOKEN }}"
      - run: |
          docker build -t registry.example.ru/app:latest .
          docker push registry.example.ru/app:latest

Коротко

Главная дыра: связка pullrequesttarget и checkout кода PR. Этот триггер нужен для узких задач вроде проставления меток, где код PR не исполняется.

Что должен найти ревьюер

  1. Безопасностьстрока 3
    pull_request_target выполняется в контексте базового репозитория с доступом к секретам. Вместе с checkout кода из PR (строка 11) это исполнение чужого кода с вашими секретами.
  2. Безопасностьстрока 11
    Checkout головы PR из форка в pull_request_target: тесты и скрипты атакующего запустятся с правами и секретами репозитория. Для проверки PR нужен pull_request.
  3. Безопасностьстрока 4
    permissions: write-all даёт токену запись во всё. Нужен минимум: contents: read, остальное точечно.
  4. Безопасностьстрока 7
    Self-hosted раннер для PR из форков: чужой код выполнится на вашей машине и в вашей сети.
  5. Безопасностьстрока 12
    Сторонний action по ветке @master: любое изменение в нём выполнится у вас. Фиксировать по SHA коммита.
  6. Ошибкастрока 13
    npm install может обновить lock-файл, сборка не воспроизводима. В CI npm ci.
  7. Безопасностьстрока 15
    Печать секрета в лог. GitHub маскирует точное значение, но любое преобразование (часть строки, base64) уже не скрывается. Секреты не выводят.
  8. Ошибкастрока 17
    Тег latest: непонятно, что задеплоено, откат невозможен. Тегировать SHA коммита.
  9. Безопасностьстрока 18
    Публикация образа в реестр из непроверенного PR: в реестр попадает код, который никто не ревьюил.

Разбор

Главная дыра: связка pull_request_target и checkout кода PR. Этот триггер нужен для узких задач вроде проставления меток, где код PR не исполняется. Для сборки и тестов PR из форков используют pull_request: секретов там нет, токен только на чтение.

Остальное это гигиена: минимальные permissions, actions по SHA, npm ci, не печатать секреты, тег по SHA, публикация образов только из main после ревью, облачные одноразовые раннеры для недоверенного кода.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.