Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
id: re-513
title: 'macOS Runners: fastlane 2.236.0 TestFlight Upload Fails — Regression Fixed in 2.236.1'
category: runner-environment
severity: error
tags:
- macos
- fastlane
- testflight
- app-store-connect
- ios
- upload-to-testflight
- regression
- gem
- 2-236-0
patterns:
- regex: 'fastlane.*testflight.*(?:fail|error|upload)|upload.*testflight.*fastlane'
flags: 'i'
- regex: 'upload_to_testflight.*error|pilot.*upload.*fail'
flags: 'i'
- regex: 'fastlane.*2\.236\.0.*testflight|testflight.*fastlane.*2\.236\.0'
flags: 'i'
error_messages:
- "fastlane upload_to_testflight failed"
- "[pilot] Error uploading to TestFlight"
- "Fastlane: Error: TestFlight upload failed (fastlane 2.236.0)"
root_cause: |
fastlane version 2.236.0 introduced a bug that prevents uploading iOS app builds to
Apple TestFlight via the `upload_to_testflight` (pilot) action. The GitHub-hosted
macOS runners ship with fastlane 2.236.0 preinstalled as of runner image version
2.335.1 (mid-June 2026), meaning all macOS runner variants are affected:
macOS 14, macOS 14 Arm64, macOS 15, macOS 15 Arm64, macOS 26, and macOS 26 Arm64.

The fastlane team confirmed and fixed the regression in fastlane 2.236.1
(see fastlane/fastlane#30065). However, the GitHub-hosted runner images may not
pick up the patch immediately, leaving the broken 2.236.0 version in the runner
image until the next image update cycle.

Workflows that use `fastlane pilot upload`, `upload_to_testflight`, or the
`deliver` action for TestFlight distribution will fail at the upload step even
though the build, signing, and packaging steps succeed normally.

Source: runner-images#14258 (June 18, 2026).
fix: |
Add a step to update fastlane via RubyGems before the upload step. This
installs fastlane 2.236.1 (or the latest patch) which contains the fix,
overriding the broken preinstalled version.

`gem update fastlane` fetches the latest fastlane from RubyGems and takes
precedence over the bundled runner image version. This step adds ~30-60 seconds
to job runtime.

Alternatively, pin `fastlane` in your `Gemfile` to `~> 2.236.1` and use
`bundle exec fastlane` so Bundler manages the version regardless of what is
preinstalled on the runner.
fix_code:
- language: yaml
label: 'Update fastlane before upload step (quick workaround)'
code: |
jobs:
deploy:
runs-on: macos-latest
steps:
- uses: actions/checkout@v7

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true

- name: Build and archive
run: fastlane gym scheme:MyApp

- name: Update fastlane (fix for 2.236.0 TestFlight regression)
run: gem update fastlane

- name: Upload to TestFlight
run: fastlane pilot upload
env:
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.ASC_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.ASC_PRIVATE_KEY }}
- language: yaml
label: 'Pin fastlane version in Gemfile (recommended long-term)'
code: |
# Gemfile — pin fastlane >= 2.236.1 to avoid the regression
# gem 'fastlane', '~> 2.236.1' # or: '>= 2.236.1'

jobs:
deploy:
runs-on: macos-latest
steps:
- uses: actions/checkout@v7

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
# Bundler installs the pinned fastlane from Gemfile.lock

- name: Build and upload
run: bundle exec fastlane deploy_testflight
# bundle exec ensures the Gemfile-pinned fastlane is used, not
# the preinstalled runner version
prevention:
- 'Pin fastlane in your `Gemfile` with a specific version range (e.g., `~> 2.236.1`) and use `bundle exec fastlane` to avoid runner image version surprises'
- 'Add a `fastlane --version` step at the start of your iOS deployment jobs to surface version mismatches in logs'
- 'Subscribe to runner-images/issues and fastlane/releases to be notified of version changes that affect preinstalled tools on macOS runners'
- 'Use the `ruby/setup-ruby` action with `bundler-cache: true` for deterministic dependency management across runner image updates'
docs:
- url: 'https://github.com/actions/runner-images/issues/14258'
label: 'runner-images#14258: macOS runners need fastlane 2.236.1 (June 18, 2026)'
- url: 'https://github.com/fastlane/fastlane/issues/30065'
label: 'fastlane/fastlane#30065: TestFlight upload regression in 2.236.0'
- url: 'https://github.com/fastlane/fastlane/releases'
label: 'fastlane releases — check latest version'
- url: 'https://docs.github.com/en/actions/use-cases-and-examples/deploying/deploying-xcode-applications'
label: 'GitHub Docs: Deploying Xcode applications with GitHub Actions'
107 changes: 107 additions & 0 deletions errors/runner-environment/ubuntu-26-04-libicu-dev-not-installed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
id: re-512
title: '`ubuntu-26.04` Runner Missing `libicu-dev` — Package Not Preinstalled'
category: runner-environment
severity: error
tags:
- ubuntu-26-04
- libicu-dev
- icu
- missing-package
- dotnet
- apt
- runner-image
- public-preview
patterns:
- regex: 'libicu-dev.*(?:is not installed|missing|not found)|(?:dpkg|apt).*libicu-dev.*not installed'
flags: 'i'
- regex: 'Error: libicu-dev is missing'
flags: 'i'
- regex: 'package .libicu-dev. is not installed'
flags: 'i'
error_messages:
- "Error: libicu-dev is missing!"
- "dpkg-query: package 'libicu-dev' is not installed and no information is available"
- "Package 'libicu-dev' is not installed"
root_cause: |
The `ubuntu-26.04` GitHub-hosted runner (public preview as of June 2026) does NOT
have `libicu-dev` preinstalled, unlike its `ubuntu-22.04` and `ubuntu-24.04`
counterparts which both include the package in the base image.

`libicu-dev` (International Components for Unicode — development headers and
libraries) is a common dependency for:
- .NET SDK / .NET Core applications that use globalization (ICU mode)
- PHP with intl extension enabled
- Ruby applications using icu gem
- Node.js native addons that link against ICU
- rpcs3 and other emulators / multimedia tools
- Many C/C++ projects that require Unicode/locale support

On `ubuntu-22.04` and `ubuntu-24.04`, workflows that rely on `libicu-dev` pass
without issue because the package is present. When the same workflow is migrated
to `ubuntu-26.04`, the dependency is missing and steps that invoke tools
requiring ICU will fail with a "missing" or "not installed" error.

This is not a regression within ubuntu-26.04 — `libicu-dev` was never included in
the ubuntu-26.04 runner image. Source: runner-images#14259 (June 19, 2026).
fix: |
Add an explicit `apt-get install` step for `libicu-dev` at the beginning of any
job that runs on `ubuntu-26.04` and requires the ICU library.

Alternatively, continue using `ubuntu-24.04` until `libicu-dev` is added to the
ubuntu-26.04 runner image (track runner-images#14259 for updates).
fix_code:
- language: yaml
label: 'Install libicu-dev before steps that require it on ubuntu-26.04'
code: |
jobs:
build:
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@v7

- name: Install libicu-dev (not preinstalled on ubuntu-26.04)
run: sudo apt-get update && sudo apt-get install -y libicu-dev

- name: Build
run: make build # or dotnet build, php artisan, etc.
- language: yaml
label: 'Conditional install for matrix builds spanning ubuntu-24.04 and ubuntu-26.04'
code: |
jobs:
build:
strategy:
matrix:
os: [ubuntu-24.04, ubuntu-26.04]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7

- name: Install libicu-dev on ubuntu-26.04
if: matrix.os == 'ubuntu-26.04'
run: sudo apt-get update && sudo apt-get install -y libicu-dev

- name: Build
run: dotnet build
- language: yaml
label: 'Stay on ubuntu-24.04 until runner-images#14259 is resolved'
code: |
jobs:
build:
# ubuntu-24.04 includes libicu-dev; use until ubuntu-26.04 image adds it
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- name: Build
run: make build
prevention:
- 'When migrating workflows from ubuntu-22.04 or ubuntu-24.04 to ubuntu-26.04, audit all `apt-get install` steps and implicit package dependencies'
- 'Check the ubuntu-26.04 installed packages list (runner-images repo) before migrating to verify that your required packages are present'
- 'Add an explicit `apt-get install` for any system library your build depends on rather than relying on runner image defaults — this makes workflows portable across ubuntu versions'
- 'Subscribe to runner-images#14259 to be notified when libicu-dev is added to ubuntu-26.04 runner images'
docs:
- url: 'https://github.com/actions/runner-images/issues/14259'
label: 'runner-images#14259: libicu-dev is not installed on ubuntu-26.04 (June 19, 2026)'
- url: 'https://github.com/actions/runner-images/issues/14226'
label: 'runner-images#14226: ubuntu-26.04 public preview announcement'
- url: 'https://packages.ubuntu.com/plucky/libicu-dev'
label: 'Ubuntu 26.04 (Plucky) — libicu-dev package info'
160 changes: 160 additions & 0 deletions errors/triggers/checkout-v7-fork-pr-blocked-pull-request-target.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
id: tr-122
title: '`actions/checkout` v7 Refuses to Check Out Fork PR Code in `pull_request_target` — Hard Error'
category: triggers
severity: error
tags:
- pull_request_target
- actions-checkout
- fork
- pwn-request
- security
- checkout-v7
- workflow_run
- breaking-change
patterns:
- regex: 'Refusing to check out fork pull request code from a .pull_request_target. workflow'
flags: 'i'
- regex: 'Refusing to check out fork pull request code from a .workflow_run. workflow'
flags: 'i'
- regex: 'allow-unsafe-pr-checkout.*pull_request_target|pull_request_target.*allow-unsafe-pr-checkout'
flags: 'i'
error_messages:
- "Error: Refusing to check out fork pull request code from a 'pull_request_target' workflow. This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner access. Fetching and executing a fork's code in that trusted context commonly leads to \"pwn request\" vulnerabilities. To opt in, review the risks at https://gh.io/securely-using-pull_request_target and set 'allow-unsafe-pr-checkout: true' on the actions/checkout step."
- "Error: Refusing to check out fork pull request code from a 'workflow_run' workflow."
root_cause: |
Starting June 18, 2026, `actions/checkout` v7.0.0 actively REFUSES to check out
fork pull request code when the workflow trigger is `pull_request_target` or
`workflow_run` (where `workflow_run.event` starts with `pull_request`).

The action throws a hard error — the step fails and the workflow is stopped — when
ANY of the following conditions are met AND the PR is from a fork:

- `repository:` resolves to the fork PR's repository
(e.g., `repository: ${{ github.event.pull_request.head.repo.full_name }}`)
- `ref:` matches `refs/pull/<number>/head` or `refs/pull/<number>/merge`
(e.g., `ref: refs/pull/${{ github.event.pull_request.number }}/merge`)
- `ref:` resolves to the fork PR's head or merge commit SHA
(e.g., `ref: ${{ github.event.pull_request.head.sha }}`)

This change closes the most common "pwn request" attack vector — a pattern that
has been the root cause of multiple supply-chain incidents. In a pwn request,
an attacker-controlled fork PR is checked out inside a privileged workflow (one
that has base repository secrets and full GITHUB_TOKEN write access), allowing
the attacker's code to exfiltrate secrets or modify repository state.

**July 16, 2026 backport:** GitHub will backport enforcement to ALL currently
supported major versions. Workflows using floating major tags such as
`actions/checkout@v4`, `@v5`, or `@v6` will automatically pick up the blocking
behavior on July 16 without any workflow file changes. Only workflows pinned to
a specific SHA, minor, or patch version are unaffected by the backport and must
upgrade manually via Dependabot or another mechanism.

Same-repository pull requests are NOT affected. The `pull_request` event (which
runs without base-repo secrets) is also NOT affected.
fix: |
**Option 1 — Remove the insecure ref/repository inputs (recommended).**
If your `pull_request_target` workflow checks out the fork PR code but does not
actually need to RUN that code with elevated access, remove the `ref:` or
`repository:` inputs. The default checkout in `pull_request_target` checks out
the BASE branch, not the PR — which is intentional and safe.

**Option 2 — Switch to `pull_request` for building and testing.**
Use `pull_request` for jobs that need to build and run the PR's code. The
`pull_request` event checks out PR changes correctly and runs without base-repo
secrets. Use `pull_request_target` only for privileged operations on trusted
(base-repo) code — labeling, commenting, triggering deployments.

**Option 3 — Opt out with `allow-unsafe-pr-checkout: true`.**
If your workflow genuinely requires checking out fork PR code with elevated trust
(e.g., generating coverage reports against a private artifact registry), you can
opt out explicitly. This is a deliberate security decision — read the guidance at
https://gh.io/securely-using-pull_request_target before opting out, and ensure
the job's permissions are scoped as narrowly as possible.

**Note:** Upgrade to `actions/checkout@v7` before July 16, 2026 to control your
timeline. After July 16, all floating major-version tags will enforce the block
automatically.
fix_code:
- language: yaml
label: 'BEFORE (broken with v7): pull_request_target checking out fork PR head'
code: |
on: pull_request_target

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7 # ERROR: refuses to checkout fork PR code
with:
ref: ${{ github.event.pull_request.head.sha }}
# ^^^ This pattern is now blocked by default in pull_request_target
- run: npm test
- language: yaml
label: 'AFTER — split into pull_request (build/test) + pull_request_target (privileged ops)'
code: |
# Workflow 1: ci.yml — pull_request handles build/test safely (no secrets)
on: pull_request

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
# default: checks out PR merge commit (correct and safe)
- run: npm ci && npm test

---
# Workflow 2: label.yml — pull_request_target for privileged labeling (base code only)
on: pull_request_target

jobs:
label:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v7
# No ref: input — defaults to base branch (safe)
- name: Apply labels
run: gh pr edit ${{ github.event.number }} --add-label "needs-review"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- language: yaml
label: 'Opt-out (for workflows that genuinely need fork code with elevated trust)'
code: |
on: pull_request_target

jobs:
coverage:
runs-on: ubuntu-latest
permissions:
# IMPORTANT: minimize permissions when checking out fork code
contents: read
pull-requests: write
# Never add: secrets:, environments:, or id-token: write here
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
allow-unsafe-pr-checkout: true # explicit opt-out — deliberate security decision
- name: Generate coverage report
run: npm run coverage
prevention:
- 'Audit all `pull_request_target` workflows for `ref: ${{ github.event.pull_request.head.sha }}` or `ref: refs/pull/*/head` patterns — these will start failing with actions/checkout@v7'
- 'Run Dependabot or `gh` to upgrade `actions/checkout` to v7 before July 16, 2026 to control when the enforcement kicks in'
- 'Use `pull_request` for build and test jobs, `pull_request_target` only for privileged metadata operations (labeling, commenting, deployment approval)'
- 'If opting out with `allow-unsafe-pr-checkout: true`, ensure the job has no secret access, no environment access, and minimal GITHUB_TOKEN permissions'
- 'Same-repo PRs are unaffected — this only blocks fork PRs, which is the pwn-request attack vector'
docs:
- url: 'https://github.blog/changelog/2026-06-18-safer-pull_request_target-defaults-for-github-actions-checkout/'
label: 'GitHub Changelog (June 18, 2026): Safer pull_request_target defaults for actions/checkout'
- url: 'https://github.com/actions/checkout/releases/tag/v7.0.0'
label: 'actions/checkout v7.0.0 release notes'
- url: 'https://github.com/actions/checkout/pull/2454'
label: 'actions/checkout PR #2454: block checking out fork PR for pull_request_target and workflow_run'
- url: 'https://gh.io/securely-using-pull_request_target'
label: 'GitHub guidance: Securely using pull_request_target'
- url: 'https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/'
label: 'GitHub Security Lab: Preventing pwn requests'
- url: 'https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions'
label: 'GitHub Docs: Security hardening for GitHub Actions'
Loading