Cross Repository Access

Cross Repository Access

Description

When a workflow checks out or clones a repository other than the one that triggered it, any secrets granted to the workflow can cross trust boundaries. Attackers can substitute malicious dependencies, exfiltrate data to forked repos, or silently tamper with code if the external repo is compromised. GitHub recommends using organization allowlists and scoped tokens for cross-repo interactions. 1

Vulnerable Instance

  • actions/checkout fetches owner/other-repo using the default GITHUB_TOKEN.
  • Workflow writes artifacts or pushes commits back to that repository.
  • There is no allowlist or validation of the requested repository name.
name: Cross Repo Sync
on:
  workflow_dispatch:
    inputs:
      target_repo:
        required: true

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Clone target repository
        run: git clone https://github.com/${{ inputs.target_repo }} target
      - name: Push changes
        run: |
          cd target
          git commit --allow-empty -m "sync"
          git push

A malicious user can supply inputs.target_repo pointing to an attacker-controlled repo, causing secrets or code to be exposed.

Mitigation Strategies

  1. Allowlist target repositories
    Check the requested repo against a regex or case statement before cloning.
  2. Use fine-grained PATs
    Replace the default GITHUB_TOKEN with repo- or org-scoped PATs that limit write operations.
  3. Pin revisions and verify sources
    When consuming code, pin to specific SHAs and configure Dependabot/CodeQL scanning.
  4. Log and audit access
    Emit telemetry when cross-repo operations run and review logs for unexpected targets.
  5. Prefer GitHub Actions Marketplace
    Use prebuilt actions from trusted publishers instead of cloning arbitrary repos.

Secure Version

 name: Approved Cross Repo Sync
 on:
   workflow_dispatch:
     inputs:
       target_repo:
-        required: true
+        type: choice
+        options:
+          - my-org/docs
+          - my-org/app
+        required: true

 jobs:
   sync:
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
       - uses: actions/checkout@v4
       - name: Clone approved repo
+        env:
+          TARGET_REPO: ${{ inputs.target_repo }}
         run: |
-          git clone https://github.com/${{ inputs.target_repo }} target
-      - name: Push changes
-        run: |
-          cd target
-          git commit --allow-empty -m "sync"
-          git push
+          case "$TARGET_REPO" in
+            my-org/docs|my-org/app) ;;
+            *) echo "Repo not allowlisted"; exit 1 ;;
+          esac
+          git clone https://github.com/$TARGET_REPO target
+      - name: Sync read-only data
+        run: rsync -a src/ target/

Impact

DimensionSeverityNotes
LikelihoodMediumCross-repo clones are common in monorepos and mirrored workflows.
RiskHighExposes secrets to untrusted repos or allows supply-chain tampering.
Blast radiusWideAny repository or service that the workflow token can reach becomes vulnerable.

References


Last updated on